LocalFilesystem
Added in: @mastra/core@1.1.0
Stores files in a directory on the local filesystem. For interface details, see WorkspaceFilesystem Interface.
UsageDirect link to Usage
Add a LocalFilesystem to a workspace and assign it to an agent. The agent can then read, write, and manage files as part of its tasks:
import { Agent } from '@mastra/core/agent'
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'
const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './workspace',
}),
})
const agent = new Agent({
id: 'file-agent',
model: 'openai/gpt-6.1-sol',
workspace,
})
// The agent now has filesystem tools available
const response = await agent.generate('List all files in the workspace')
Constructor parametersDirect link to Constructor parameters
basePath:
id?:
contained?:
allowedPaths?:
basePath.instructions?:
readOnly?:
PropertiesDirect link to Properties
id:
name:
provider:
basePath:
readOnly:
allowedPaths:
MethodsDirect link to Methods
init()Direct link to init
Initialize the filesystem. Creates the base directory if it doesn't exist.
await filesystem.init()
Called by workspace.init().
Lazy initializationDirect link to Lazy initialization
LocalFilesystem initializes on first operation if not already initialized, creating the base directory automatically. Calling init() explicitly is optional but can be useful to pre-create directories before the first operation.
destroy()Direct link to destroy
Clean up filesystem resources.
await filesystem.destroy()
Called by workspace.destroy().
setAllowedPaths(pathsOrUpdater)Direct link to setallowedpathspathsorupdater
Update the allowed paths at runtime. Accepts a new paths array (replaces current) or an updater callback that receives the current paths and returns the new set.
// Set directly
filesystem.setAllowedPaths(['/home/user/.config'])
// Update with callback
filesystem.setAllowedPaths(prev => [...prev, '/home/user/documents'])
// Clear all allowed paths
filesystem.setAllowedPaths([])
Parameters:
pathsOrUpdater:
readFile(path, options?)Direct link to readfilepath-options
Read file contents.
const content = await filesystem.readFile('docs/guide.md', { encoding: 'utf-8' })
const buffer = await filesystem.readFile('image.png')
Parameters:
path:
options?:
encoding?:
writeFile(path, content, options?)Direct link to writefilepath-content-options
Write content to a file.
await filesystem.writeFile('docs/new.md', '# New Document')
await filesystem.writeFile('nested/path/file.md', content, { recursive: true })
Parameters:
path:
content:
options?:
recursive?:
overwrite?:
expectedMtime?:
appendFile(path, content)Direct link to appendfilepath-content
Append content to an existing file.
await filesystem.appendFile('logs/app.log', 'New log entry\n')
Parameters:
path:
content:
deleteFile(path, options?)Direct link to deletefilepath-options
Delete a file.
await filesystem.deleteFile('docs/old.md')
await filesystem.deleteFile('docs/maybe.md', { force: true }) // Don't throw if missing
Parameters:
path:
options?:
force?:
copyFile(src, dest, options?)Direct link to copyfilesrc-dest-options
Copy a file to a new location.
await filesystem.copyFile('docs/template.md', 'docs/new-doc.md')
await filesystem.copyFile('src/config.json', 'backup/config.json', { overwrite: false })
Parameters:
src:
dest:
options?:
overwrite?:
moveFile(src, dest, options?)Direct link to movefilesrc-dest-options
Move or rename a file.
await filesystem.moveFile('docs/draft.md', 'docs/final.md')
await filesystem.moveFile('temp/upload.txt', 'files/document.txt')
Parameters:
src:
dest:
options?:
overwrite?:
mkdir(path, options?)Direct link to mkdirpath-options
Create a directory.
await filesystem.mkdir('docs/api')
await filesystem.mkdir('deeply/nested/path', { recursive: true })
Parameters:
path:
options?:
recursive?:
rmdir(path, options?)Direct link to rmdirpath-options
Remove a directory.
await filesystem.rmdir('docs/old')
await filesystem.rmdir('docs/nested', { recursive: true })
Parameters:
path:
options?:
recursive?:
force?:
readdir(path, options?)Direct link to readdirpath-options
List directory contents.
const entries = await filesystem.readdir('docs')
// [{ name: 'guide.md', type: 'file' }, { name: 'api', type: 'directory' }]
// List the basePath root
const rootEntries = await filesystem.readdir('.')
exists(path)Direct link to existspath
Check if a path exists.
const exists = await filesystem.exists('docs/guide.md')
stat(path)Direct link to statpath
Get file or directory metadata.
const stat = await filesystem.stat('docs/guide.md')
// { type: 'file', size: 1234, modifiedAt: Date, createdAt: Date, path: 'docs/guide.md' }
getInfo()Direct link to getinfo
Returns metadata about this filesystem instance.
const info = filesystem.getInfo()
// { id: '...', name: 'LocalFilesystem', provider: 'local', basePath: '/workspace', readOnly: false }
getInstructions(opts?)Direct link to getinstructionsopts
Returns a description of how paths work in this filesystem. When assigned to an agent, this is injected into the agent's system message.
const instructions = filesystem.getInstructions()
// 'Local filesystem at "/workspace". Relative paths resolve from this directory. File access is restricted to this directory.'
Pass requestContext to enable per-request customization when the instructions constructor option is a function:
const instructions = filesystem.getInstructions({ requestContext })
Parameters:
opts.requestContext?:
instructions function if one was provided in the constructor.Returns: string
To override the default output, pass an instructions option to the constructor. See constructor parameters.
Path resolutionDirect link to Path resolution
How basePath worksDirect link to how-basepath-works
The basePath option sets the root directory for all file operations. Paths passed to methods like readFile() are resolved as follows:
- Relative paths are resolved against
basePath:docs/guide.md→<basePath>/docs/guide.md - Use
.to refer to the root ofbasePath, for examplereaddir('.') - Absolute paths are treated as host paths, not as paths inside
basePath. With the defaultcontained: true, any absolute path that falls outsidebasePathand the configuredallowedPathsis rejected with aPermissionError ~expands to the user's home directory, so it's also a host path and is subject to the same containment rules
const filesystem = new LocalFilesystem({
basePath: './workspace',
})
// Resolves to ./workspace/docs/guide.md
await filesystem.readFile('docs/guide.md')
await filesystem.readFile('./docs/guide.md')
// Root of basePath
await filesystem.readdir('.')
// Throws a PermissionError with the default contained: true
await filesystem.readFile('/docs/guide.md')
To read host absolute paths outside basePath, add them to allowedPaths or set contained: false. Prefer allowedPaths when only a few external directories are needed.
const filesystem = new LocalFilesystem({
basePath: './workspace',
allowedPaths: ['/home/user/shared-docs'],
})
await filesystem.readFile('/home/user/shared-docs/guide.md')
Mounted filesystemsDirect link to Mounted filesystems
When a LocalFilesystem is mounted in a workspace through CompositeFilesystem, workspace-facing paths include the mount prefix. For example, with a mount at /workspace, the workspace path /workspace/report.md is passed to the underlying filesystem as report.md, relative to its basePath. See Filesystem mounts for mount configuration.
Relative paths and execution contextDirect link to Relative paths and execution context
When you use a relative path for basePath, it resolves from process.cwd(). In Mastra projects, the cwd changes based on how you run your code:
| Context | Working directory | ./workspace resolves to |
|---|---|---|
mastra dev | ./src/mastra/public/ | ./src/mastra/public/workspace |
mastra start | ./.mastra/output/ | ./.mastra/output/workspace |
| Direct script | Where you ran the command | Relative to that location |
This can cause confusion when the same relative path resolves to different locations.
Recommended: Use absolute pathsDirect link to Recommended: Use absolute paths
For consistent paths across all execution contexts, use an environment variable with an absolute path:
import { LocalFilesystem } from '@mastra/core/workspace'
const filesystem = new LocalFilesystem({
basePath: process.env.WORKSPACE_PATH!,
})
Set WORKSPACE_PATH in your environment to an absolute path like /home/user/my-project/workspace. It ensures the workspace path is consistent regardless of how you run your code.