You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(tools): sandbox FileWriterTool writes and fix file tool rough edges
FileReadTool confined reads to the working directory, but FileWriterTool
only checked that `filename` stayed inside `directory` — and `directory`
itself is an LLM-supplied schema field. An agent could therefore write
anywhere the process had permission to, including ~/.ssh and site-packages,
while the reader refused to read back what the writer had just written.
FileWriterTool was the only filesystem tool in the package that did not go
through validate_file_path; files_compressor_tool validates even its
output path.
Writes are now confined to base_dir (the working directory by default):
the resolved directory must sit inside base_dir, and the resolved file
must sit inside that directory. The pre-existing filename containment
check is kept as-is and still applies even when the unsafe-paths escape
hatch is on, so no existing guarantee is weakened.
Both tools gain a base_dir field so a developer can widen the sandbox
deliberately instead of reaching for the process-wide
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS kill switch. FileReadTool also stops
rejecting a file_path given to its own constructor: that is
developer-declared intent, and declaring one file does not expose its
siblings.
Also fixed:
- FileReadTool scanned the whole file when reading a line window; it now
stops via islice once the requested lines are collected.
- FileWriterTool._run(**kwargs) made the documented positional call
signature raise TypeError and turned a missing overwrite into
"error accessing key". It now takes named parameters in the documented
(filename, content, directory) order.
- A directory naming an existing file reported "already exists and
overwrite option was not passed" even with overwrite=True; it now
explains the real problem.
- Subdirectories inside filename are created, matching what passing
directory already did.
- Both tools now write and decode UTF-8 by default instead of the
platform locale encoding, with an encoding field to override. The docs
already claimed UTF-8 and recommended the writer to Windows users.
- The writer's schema fields had no descriptions for the LLM.
- Docs claimed FileReadTool parses JSON into a dict (it never has),
shipped a snippet that raised TypeError, and did not mention the path
sandbox. The writer README also began with a stray "Here's the
rewritten README" preamble.
BREAKING CHANGE: FileWriterTool no longer writes outside the working
directory. Pass base_dir to authorize a different tree.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/edge/ar/tools/file-document/filereadtool.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ mode: "wide"
11
11
لا نزال نعمل على تحسين الأدوات، لذا قد يحدث سلوك غير متوقع أو تغييرات في المستقبل.
12
12
</Note>
13
13
14
-
تمثل أداة FileReadTool مفهومياً مجموعة من الوظائف ضمن حزمة crewai_tools تهدف إلى تسهيل قراءة الملفات واسترجاع المحتوى. تتضمن هذه المجموعة أدوات لمعالجة ملفات نصية دفعية، وقراءة ملفات التكوين أثناء التشغيل، واستيراد البيانات للتحليلات. تدعم مجموعة متنوعة من صيغ الملفات النصية مثل `.txt` و `.csv` و `.json` وغيرها. اعتماداً على نوع الملف، توفر المجموعة وظائف متخصصة، مثل تحويل محتوى JSON إلى قاموس Python لسهولة الاستخدام.
14
+
تمثل أداة FileReadTool مفهومياً مجموعة من الوظائف ضمن حزمة crewai_tools تهدف إلى تسهيل قراءة الملفات واسترجاع المحتوى. تتضمن هذه المجموعة أدوات لمعالجة ملفات نصية دفعية، وقراءة ملفات التكوين أثناء التشغيل، واستيراد البيانات للتحليلات. تدعم مجموعة متنوعة من صيغ الملفات النصية مثل `.txt` و `.csv` و `.json` وغيرها. يُعاد المحتوى دائماً كنص عادي.
Copy file name to clipboardExpand all lines: docs/edge/en/tools/file-document/filereadtool.mdx
+42-7Lines changed: 42 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,10 +11,12 @@ mode: "wide"
11
11
We are still working on improving tools, so there might be unexpected behavior or changes in the future.
12
12
</Note>
13
13
14
-
The FileReadTool conceptually represents a suite of functionalities within the crewai_tools package aimed at facilitating file reading and content retrieval.
15
-
This suite includes tools for processing batch text files, reading runtime configuration files, and importing data for analytics.
16
-
It supports a variety of text-based file formats such as `.txt`, `.csv`, `.json`, and more. Depending on the file type, the suite offers specialized functionality,
17
-
such as converting JSON content into a Python dictionary for ease of use.
14
+
The `FileReadTool` reads the contents of a file from the local file system and returns it as text.
15
+
It is useful for batch text file processing, reading runtime configuration files, and importing data for analytics.
16
+
It supports any text-based file format, such as `.txt`, `.csv`, `.json`, and `.md`.
17
+
Content is always returned as plain text — parsing it (for example, `json.loads` on a `.json` file) is up to the agent or your own code.
18
+
19
+
For large files, `start_line` and `line_count` read just a window of lines instead of loading the whole file.
18
20
19
21
## Installation
20
22
@@ -31,15 +33,48 @@ To get started with the FileReadTool:
31
33
```python Code
32
34
from crewai_tools import FileReadTool
33
35
34
-
# Initialize the tool to read any files the agents knows or lean the path for
36
+
# Initialize the tool to read any file the agent knows or learns the path for
35
37
file_read_tool = FileReadTool()
36
38
37
39
# OR
38
40
39
-
# Initialize the tool with a specific file path, so the agent can only read the content of the specified file
41
+
# Initialize with a specific file path, so the agent reads that file by default
# Read a window of lines (lines 100-149) instead of the whole file
45
+
partial_content = file_read_tool.run(
46
+
file_path='path/to/your/file.txt',
47
+
start_line=100,
48
+
line_count=50,
49
+
)
41
50
```
42
51
43
52
## Arguments
44
53
45
-
-`file_path`: The path to the file you want to read. It accepts both absolute and relative paths. Ensure the file exists and you have the necessary permissions to access it.
54
+
The agent supplies these at runtime:
55
+
56
+
-`file_path`: The path to the file you want to read. Accepts absolute and relative paths. Ensure the file exists and you have the necessary permissions to access it.
57
+
-`start_line`: (Optional) The line number to start reading from (1-indexed). Defaults to `1`.
58
+
-`line_count`: (Optional) The number of lines to read. If omitted, reads from `start_line` to the end of the file.
59
+
60
+
You set these when constructing the tool:
61
+
62
+
-`file_path`: (Optional) A default file to read when the agent calls the tool with no arguments.
63
+
-`base_dir`: (Optional) The directory that runtime paths must stay inside. Defaults to the current working directory.
64
+
-`encoding`: (Optional) Text encoding used to decode the file. Defaults to `utf-8`.
65
+
66
+
## Allowed paths
67
+
68
+
Because the file path is usually chosen by an LLM at runtime, reads are confined to a sandbox:
69
+
70
+
- Paths supplied at runtime must resolve inside `base_dir`, which defaults to the current working directory. `..` segments and symlinks are resolved before the check, so they cannot be used to escape.
71
+
- A `file_path` passed to the constructor is developer-declared intent, so it is always readable — even outside `base_dir`. Declaring one file does not expose its siblings.
72
+
73
+
To let an agent read a directory tree outside the working directory, point `base_dir` at it:
74
+
75
+
```python Code
76
+
# The agent may read anything under /data, and nothing outside it
77
+
file_read_tool = FileReadTool(base_dir='/data')
78
+
```
79
+
80
+
As a last resort, setting `CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true` disables path validation. This applies process-wide to every crewai-tools tool, including the SSRF protections on URL-fetching tools, so prefer `base_dir`.
Copy file name to clipboardExpand all lines: docs/edge/en/tools/file-document/filewritetool.mdx
+35-5Lines changed: 35 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ mode: "wide"
11
11
12
12
The `FileWriterTool` is a component of the crewai_tools package, designed to simplify the process of writing content to files with cross-platform compatibility (Windows, Linux, macOS).
13
13
It is particularly useful in scenarios such as generating reports, saving logs, creating configuration files, and more.
14
-
This tool handles path differences across operating systems, supports UTF-8 encoding, and automatically creates directories if they don't exist, making it easier to organize your output reliably across different platforms.
14
+
This tool handles path differences across operating systems, writes UTF-8 by default rather than the platform's locale encoding, and automatically creates directories if they don't exist, making it easier to organize your output reliably across different platforms.
15
15
16
16
## Installation
17
17
@@ -32,15 +32,45 @@ from crewai_tools import FileWriterTool
32
32
file_writer_tool = FileWriterTool()
33
33
34
34
# Write content to a file in a specified directory
35
-
result = file_writer_tool._run('example.txt', 'This is a test content.', 'test_directory')
35
+
result = file_writer_tool.run(
36
+
filename='example.txt',
37
+
content='This is a test content.',
38
+
directory='test_directory',
39
+
)
36
40
print(result)
37
41
```
38
42
39
43
## Arguments
40
44
41
-
-`filename`: The name of the file you want to create or overwrite.
42
-
-`content`: The content to write into the file.
43
-
-`directory` (optional): The path to the directory where the file will be created. Defaults to the current directory (`.`). If the directory does not exist, it will be created.
45
+
The agent supplies these at runtime:
46
+
47
+
-`filename`: The name of the file to write, relative to `directory`. May include subdirectories, which are created if they don't exist.
48
+
-`content`: The text content to write into the file.
49
+
-`directory` (optional): The path to the directory where the file will be created. Defaults to the current working directory. If the directory does not exist, it will be created.
50
+
-`overwrite` (optional): Whether to replace the file when it already exists. Accepts `true`/`false` (also `yes`/`no`, `on`/`off`, `1`/`0`). Defaults to `false`, which reports an error instead of replacing existing content.
51
+
52
+
You set these when constructing the tool:
53
+
54
+
-`base_dir` (optional): The directory that writes must stay inside. Defaults to the current working directory.
55
+
-`encoding` (optional): Text encoding used to write the file. Defaults to `utf-8`.
56
+
57
+
## Allowed paths
58
+
59
+
Because both the directory and the filename are usually chosen by an LLM at runtime, writes are confined to a sandbox:
60
+
61
+
- The resolved `directory` must be inside `base_dir`, which defaults to the current working directory.
62
+
- The resolved file must then be inside that `directory`. `..` segments, absolute paths, and symlinks are resolved before both checks, so they cannot be used to escape.
63
+
64
+
To let an agent write outside the working directory, point `base_dir` at the target tree:
65
+
66
+
```python Code
67
+
# The agent may write anywhere under /var/output, and nowhere outside it
Previously an absolute `directory` could write anywhere the process had permission to. If you relied on that, set `base_dir` to the tree you want to allow. Setting `CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true` restores the old behavior, but it applies process-wide to every crewai-tools tool, including the SSRF protections on URL-fetching tools, so prefer `base_dir`.
Copy file name to clipboardExpand all lines: docs/edge/pt-BR/tools/file-document/filereadtool.mdx
+1-2Lines changed: 1 addition & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,8 +13,7 @@ mode: "wide"
13
13
14
14
O FileReadTool representa conceitualmente um conjunto de funcionalidades dentro do pacote crewai_tools voltadas para facilitar a leitura e a recuperação de conteúdo de arquivos.
15
15
Esse conjunto inclui ferramentas para processar arquivos de texto em lote, ler arquivos de configuração em tempo de execução e importar dados para análise.
16
-
Ele suporta uma variedade de formatos de arquivo baseados em texto, como `.txt`, `.csv`, `.json` e outros. Dependendo do tipo de arquivo, o conjunto oferece funcionalidades especializadas,
17
-
como converter conteúdo JSON em um dicionário Python para facilitar o uso.
16
+
Ele suporta uma variedade de formatos de arquivo baseados em texto, como `.txt`, `.csv`, `.json` e outros. O conteúdo é sempre retornado como texto simples.
Copy file name to clipboardExpand all lines: lib/crewai-tools/src/crewai_tools/tools/file_read_tool/README.md
+28-4Lines changed: 28 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,9 +2,9 @@
2
2
3
3
## Description
4
4
5
-
The FileReadTool is a versatile component of the crewai_tools package, designed to streamline the process of reading and retrieving content from files. It is particularly useful in scenarios such as batch text file processing, runtime configuration file reading, and data importation for analytics. This tool supports various text-based file formats including `.txt`, `.csv`, `.json`, and adapts its functionality based on the file type, for instance, converting JSON content into a Python dictionary for easy use.
5
+
The FileReadTool is a versatile component of the crewai_tools package, designed to streamline the process of reading and retrieving content from files. It is particularly useful in scenarios such as batch text file processing, runtime configuration file reading, and data importation for analytics. This tool supports any text-based file format, including `.txt`, `.csv`, `.json`, and `.md`. Content is always returned as plain text — parsing it (for example, `json.loads` on a `.json` file) is up to the agent or your own code.
6
6
7
-
The tool also supports reading specific chunks of a file by specifying a starting line and the number of lines to read, which is helpful when working with large files that don't need to be loaded entirely into memory.
7
+
The tool also supports reading specific chunks of a file by specifying a starting line and the number of lines to read, which is helpful when working with large files that don't need to be loaded entirely into memory. Reading a window stops as soon as the requested lines have been collected, so it does not scan the rest of the file.
8
8
9
9
## Installation
10
10
@@ -21,12 +21,12 @@ To get started with the FileReadTool:
21
21
```python
22
22
from crewai_tools import FileReadTool
23
23
24
-
# Initialize the tool to read any files the agents knows or lean the path for
24
+
# Initialize the tool to read any file the agent knows or learns the path for
25
25
file_read_tool = FileReadTool()
26
26
27
27
# OR
28
28
29
-
# Initialize the tool with a specific file path, so the agent can only read the content of the specified file
29
+
# Initialize the tool with a specific file path, so the agent reads that file by default
-`file_path`: The path to the file you want to read. It accepts both absolute and relative paths. Ensure the file exists and you have the necessary permissions to access it.
39
41
-`start_line`: (Optional) The line number to start reading from (1-indexed). Defaults to 1 (the first line).
40
42
-`line_count`: (Optional) The number of lines to read. If not provided, reads from the start_line to the end of the file.
43
+
44
+
You set these when constructing the tool:
45
+
46
+
-`file_path`: (Optional) A default file to read when the agent calls the tool with no arguments.
47
+
-`base_dir`: (Optional) The directory that runtime paths must stay inside. Defaults to the current working directory.
48
+
-`encoding`: (Optional) Text encoding used to decode the file. Defaults to `utf-8`.
49
+
50
+
## Allowed paths
51
+
52
+
Because the file path is usually chosen by an LLM at runtime, reads are confined to a sandbox:
53
+
54
+
- Paths supplied at runtime must resolve inside `base_dir` (the current working directory by default). `..` segments and symlinks are resolved before the check, so they cannot be used to escape.
55
+
- A `file_path` passed to the constructor is developer-declared intent, so it is always readable — even outside `base_dir`. Declaring one file does not expose its siblings.
56
+
57
+
To let an agent read a directory tree outside the working directory, point `base_dir` at it:
58
+
59
+
```python
60
+
# The agent may read anything under /data, and nothing outside it
61
+
file_read_tool = FileReadTool(base_dir='/data')
62
+
```
63
+
64
+
Setting `CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true` disables path validation, but it applies process-wide to every crewai-tools tool, including the SSRF protections on URL-fetching tools, so prefer `base_dir`.
0 commit comments