Skip to content

Default Tools - Filesystem

The 18 tools in default-tool-specs-builtin-fs.json are the safety.fs surface as ready-to-call tools - a shell-style filesystem pipeline covering list-roots, read, list, stat, grep, recursive content search, count, slice, sort, cut, find, write, append, targeted edit, copy, move, and delete (file and directory). They operate within two boundaries:

  • Readable roots - directories the tools may read from, recursively. The user's home directory is a readable root by default.
  • A working directory (spring.ai.playground.tool-studio.fs.base-path, default ${user.home}/spring-ai-playground/workspace) - the only writable location, and where relative paths resolve. When a tool runs inside a chat, writes are confined to a per-conversation subdirectory of it (<workspace>/<conversationId>/), created on first write and removed when you delete the conversation; listAllowedDirectories reports that exact path at runtime. This holds however the chat reaches the tool - a fixed selection travels through the built-in MCP server's loopback connection, which carries the conversation identity along with the call. A caller with no conversation - an external MCP client invoking the same exposed tools - writes to the working directory root instead.

So a relative path resolves under the working directory; an absolute path may be read anywhere under a readable root, but writes are confined to the working directory. Call listAllowedDirectories first to learn the exact absolute paths before reading or writing.

Three capability tiers. Read tools (listDir, readTextFile, grepFile, searchInFiles, ...) need only fileRead and rank L3. Write tools that create or amend a file (writeTextFile, appendTextFile, editTextFile, copyFile) need fileWrite and rank L4. Tools that remove or relocate data (moveFile, deleteFile, deleteDir) carry a destructive flag and rank L5 - deliberately above a plain overwrite, because the loss is not recoverable from the file itself. Every write and destructive tool is gated by human-in-the-loop approval, so its risk chip shows two levels with an arrow (L5 → L4, L4 → L3): the level before the arrow is the inherent posture that still drives sandbox permissions and the audit log, and the level after is the effective posture once a mandatory approval is credited (one band lower). A poisoned tool description forfeits that credit, and the runtime denies the call outright if approval is unavailable, so a credited mitigation can never silently no-op.

Because they ride on java.nio.file.Path / Files, separator handling (/ vs \), case folding, and symlink semantics are normalised at the JVM layer - these tools behave identically on macOS, Windows, and Linux. See Tool Studio: Cross-platform by design for the mechanics, and Tool Studio: Filesystem mode for the read-only / read-write sandbox split.

The 18 filesystem tools

listAllowedDirectories 🆓

file · pipeline L3

Reports the filesystem boundaries these tools operate within: the readable roots (anything under them can be read) and the working directory (the only writable location; a per-conversation subdirectory when run from a chat). Call this first. Uses safety.fs.readRoots() / workspace().

Params   -

Env       -

Click for full reference · params · sandbox · JS source
readTextFile 🆓

file · pipeline L3

Reads a UTF-8 text file from disk and returns its contents as a single string.

Params   path

Env       -

Click for full reference · params · sandbox · JS source
listDir 🆓

file · pipeline L3

Lists the immediate entries (files and subdirectories) of a directory. Entries in the working directory come back as relative names; entries elsewhere under a readable root come back as absolute paths. Uses safety.fs.list().

Params   dir

Env       -

Click for full reference · params · sandbox · JS source
statFile 🆓

file · pipeline L3

Returns size, last-modified timestamp, and a directory flag for a path (relative under the working directory, or absolute under a readable root). Uses safety.fs.stat().

Params   path

Env       -

Click for full reference · params · sandbox · JS source
lineCount 🆓

file · pipeline L3

Counts the lines in a UTF-8 text file. Uses safety.fs.lineCount().

Params   path

Env       -

Click for full reference · params · sandbox · JS source
sliceFile 🆓

file · pipeline L3

Returns a slice of lines from a UTF-8 text file (head / tail / range). start is 0-based inclusive, end is 0-based exclusive (Python-style slice). Negative values count from the end of the file. Uses safety.fs.slice().

Params   path · start · end

Env       -

Click for full reference · params · sandbox · JS source
sortFile 🆓

file · pipeline L3

Sorts the lines of a UTF-8 text file and returns the sorted lines as an array. Options: reverse / numeric / caseInsensitive / unique. Uses safety.fs.sort().

Params   path · reverse · numeric · caseInsensitive · unique

Env       -

Click for full reference · params · sandbox · JS source
grepFile 🆓

file · pipeline L3

Searches a UTF-8 text file for lines matching a JavaScript regex. Returns an array of matching lines (optionally numbered). Uses safety.fs.grep().

Params   pattern · path · caseInsensitive · numbered · limit

Env       -

Click for full reference · params · sandbox · JS source
findFiles 🆓

file · pipeline L3

Recursively finds files matching a glob inside a directory. Glob supports * and ?. Optional max recursion depth and type filter ('file' or 'dir'). Uses safety.fs.find().

Params   dir · glob · maxDepth · type

Env       -

Click for full reference · params · sandbox · JS source
cutFileFields 🆓

file · pipeline L3

Extracts selected fields from each line of a delimited file (CSV/TSV/etc.). Uses safety.fs.cut(). 1-based field numbers, comma-separated alternatives via the array.

Params   path · fields · delimiter · regex

Env       -

Click for full reference · params · sandbox · JS source
writeTextFile 🆓

file · pipeline L4

Writes a UTF-8 text file inside the working directory (creating parent directories as needed). Overwrites any existing file. Requires fileWrite permission on the sandbox.

Params   path · content

Env       -

Click for full reference · params · sandbox · JS source
searchInFiles 🆓

file · pipeline L3

Recursively searches file contents across a directory tree for lines matching a regex, returning each hit as { file, line, text }. Where grepFile scans one file, this opens every file under dir whose name matches glob. Uses safety.fs.searchInFiles().

Params   pattern · dir · glob · caseInsensitive · maxDepth · limit

Env       -

Click for full reference · params · sandbox · JS source
appendTextFile 🆓

file · pipeline L4

Appends UTF-8 text to the end of a file, creating it if absent. Unlike writeTextFile (which overwrites), this adds after the existing bytes - ideal for logs and incremental output. Uses safety.fs.appendText().

Params   path · content

Env       -

Click for full reference · params · sandbox · JS source
editTextFile 🆓

file · pipeline L4

Makes a targeted edit by replacing an exact substring, without rewriting the whole file. By default oldString must occur exactly once (else rejected as ambiguous); replaceAll swaps every occurrence. Uses safety.fs.editText().

Params   path · oldString · newString · replaceAll

Env       -

Click for full reference · params · sandbox · JS source
copyFile 🆓

file · pipeline L4

Copies a file to a new location. The source may be any readable file (a readable root, or an upload); the destination must be inside the working directory. The source is left intact. Uses safety.fs.copy().

Params   from · to

Env       -

Click for full reference · params · sandbox · JS source
moveFile 🆓

file · pipeline L5

Moves or renames a file within the working directory. Destructive: the source no longer exists at its old path afterwards, and an existing destination is overwritten. Uses safety.fs.move().

Params   from · to

Env       -

Click for full reference · params · sandbox · JS source
deleteFile 🆓

file · pipeline L5

Permanently deletes a single file from the working directory. Destructive and irreversible. Directories are rejected - use deleteDir. Uses safety.fs.delete().

Params   path

Env       -

Click for full reference · params · sandbox · JS source
deleteDir 🆓

file · pipeline L5

Permanently deletes a directory and all of its contents (recursive) from the working directory. Destructive and irreversible. The workspace root itself and plain files are rejected. Uses safety.fs.deleteDir().

Params   path

Env       -

Click for full reference · params · sandbox · JS source

Composition patterns (shell-style filesystem chains)

These tools mirror the standard Unix-shell pipeline shape, but every step is a JSON-returning function so the agent can reason between calls:

  • Read → filter → trim → save - listDir(dir)grepFile(pattern, path)sliceFile(path, start, end)writeTextFile(outPath, content). The canonical "summarise recent errors from a log directory" flow.
  • Find → cut → ETL - findFiles(dir, glob='*.csv') → loop with cutFileFields(path, fields=[1,3]) to project a directory of CSVs into one structured dataset.
  • Sort dedupe → count - sortFile(path, numeric=true, unique=true)lineCount(path) to deduplicate a numeric stream in place and report the resulting size.
  • Stat-first guard - statFile(path) → branch on size / lastModified → only run the rest of the pipeline if the file changed since the last run.
  • Search → edit - searchInFiles(dir, glob, pattern) finds every hit across the tree, then editTextFile(path, oldString, newString) applies a targeted, unique-match change to each file - the code-refactor loop.
  • Copy → transform → clean up - copyFile(upload, 'work.csv') pulls an upload into the writable workspace; process it, then deleteFile('work.csv') or deleteDir('tmp') removes the scratch copy. Every write and destructive step pauses for approval first.

Tutorial 8: Default Tool Recipes walks the Read → filter → trim → save chain end-to-end as summariseRecentLogs.

Keys & secrets

One configuration value, no real secrets.

Variable What it does Default Where to set
SPRING_AI_PLAYGROUND_TOOL_STUDIO_FS_BASE_PATH The safety.fs working directory - the only writable location, and where relative paths resolve. Reads also reach the readable roots (the home directory by default). ${user.home}/spring-ai-playground/workspace Launcher Environment Variables card, or export SPRING_AI_PLAYGROUND_TOOL_STUDIO_FS_BASE_PATH=/path before launch

The File Toolkit preset opts every read tool (now including searchInFiles) into fileRead automatically. The write tools (writeTextFile, appendTextFile, editTextFile, copyFile) require fileWrite (L4), and the destructive tools (moveFile, deleteFile, deleteDir) additionally carry the destructive flag (L5); you enable these per-tool in the Sandbox & Capabilities pane - see Tool Studio: Filesystem mode. In Agentic Chat, the Workspace organizer preset wires the full set - survey, restructure, clean up - with every mutating call gated by human-in-the-loop approval.

Tool Studio: Filesystem mode - fileRead / fileWrite semantics and base-path enforcement.