Filesystem
A filesystem gives an agent tools for reading, writing, listing, and searching files. Use it as a knowledge base or to persist files between ephemeral sandbox runs.
Configure files in two ways:
- Direct filesystem access uses
filesystemwith one filesystem provider or aCompositeFilesystemthat you create yourself. - Mounts uses
mountsto create aCompositeFilesystemfrom path-prefixed providers. When a static sandbox and filesystem provider support mounting, Mastra automatically mounts the provider at its configured path. Remote sandbox mounts typically use Filesystem in Userspace (FUSE).
Configure either filesystem or mounts, not both. Configuring both throws a WorkspaceError with the code INVALID_CONFIG.
Both configurations give the agent file tools. Sandbox commands can only see a provider when the sandbox can mount it successfully.
Configuring a filesystem gives the agent these tools:
| Tool | Does |
|---|---|
read_file | Reads all or part of a file. |
write_file | Creates or overwrites a file. |
edit_file | Replaces matching text in an existing file. |
list_files | Lists files and directories. |
delete | Deletes a file or directory. |
file_stat | Returns metadata about a file or directory. |
mkdir | Creates a directory and any missing parent directories. |
grep | Searches file contents with a regular expression. |
ast_edit | Applies structural code edits. Available when @ast-grep/napi is installed. |
Supported filesystemsDirect link to Supported filesystems
LocalFilesystemDirect link to localfilesystem
LocalFilesystem connects to a directory on the same machine as your Mastra application. Use it for local development or files that already live on the application host.
Other filesystemsDirect link to Other filesystems
Use another provider when files live outside the application host or already exist in an external service:
Every provider supports file tools through filesystem. Sandbox mounting depends on both the filesystem provider and sandbox backend.
Direct filesystem accessDirect link to Direct filesystem access
Use filesystem when the agent should access a provider through file tools. It can also accept a resolver or a manually created CompositeFilesystem.
Give an agent file tools for a local knowledge base:
import { LocalFilesystem, Workspace } from '@mastra/core/workspace'
const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './knowledge-base',
}),
})
The agent receives tools such as read_file, write_file, list_files, and grep. Paths are resolved under ./knowledge-base, and no sandbox or command tools are required.
See Search to index the files for keyword or semantic retrieval. See the filesystem tools reference for every generated tool and its policies.
MountsDirect link to Mounts
Use mounts when programs inside a sandbox need to access persistent files by path. Mastra creates the mount automatically when the sandbox and filesystem provider support it. The agent still receives file tools, while command tools can run commands such as ls, cat, or python against the same files.
For example, mount an S3 bucket at /workspace inside a Daytona sandbox:
import { Mastra } from '@mastra/core'
import { Workspace } from '@mastra/core/workspace'
import { DaytonaSandbox } from '@mastra/daytona'
import { S3Filesystem } from '@mastra/s3'
const workspace = new Workspace({
mounts: {
'/workspace': new S3Filesystem({
bucket: process.env.S3_BUCKET!,
region: 'us-east-1',
}),
},
sandbox: new DaytonaSandbox(),
})
export const mastra = new Mastra({ workspace })
Using mountsDirect link to Using mounts
Files already available through the provider appear under /workspace. The agent can call read_file('/workspace/report.md') or run cat /workspace/report.md. Files written through either interface are saved by the provider and remain available after the sandbox stops.
Without a mount, an agent can still combine file tools with sandbox commands by passing file contents between tool calls. This works for selected text files. Mounts are a better fit when programs expect a directory tree or need to process large or binary files.
File-tool and command-tool policies are independent. Requiring approval for write_file, for example, doesn't stop the agent from using execute_command to write the same mounted path. If files must only be accessed through file tools, disable sandbox command tools.
PathsDirect link to Paths
A mount path is the path exposed to file tools and, after a successful sandbox mount, commands. The underlying provider may store those files somewhere else.
For a remote provider mounted at /workspace:
- File tools use paths such as
/workspace/report.md. - Remote sandbox commands generally use the same path.
- The provider maps the path to its configured bucket, prefix, or remote directory.
LocalSandbox creates a symlink inside its workingDirectory instead. A /workspace mount becomes <workingDirectory>/workspace on the host and is usually addressed as workspace by commands.
Composite filesystemDirect link to Composite filesystem
The mounts option creates a CompositeFilesystem. This TypeScript path router presents several providers as one virtual directory tree.
Multiple filesystemsDirect link to Multiple filesystems
Configure each provider under its mount path:
import { Workspace } from '@mastra/core/workspace'
import { E2BSandbox } from '@mastra/e2b'
import { GCSFilesystem } from '@mastra/gcs'
import { S3Filesystem } from '@mastra/s3'
const workspace = new Workspace({
mounts: {
'/data': new S3Filesystem({
bucket: 'agent-data',
region: 'us-east-1',
}),
'/reports': new GCSFilesystem({
bucket: 'agent-reports',
}),
},
sandbox: new E2BSandbox({ id: 'analysis-sandbox' }),
})
With this configuration:
list_files('/')returns the virtual directoriesdataandreports.read_file('/data/input.csv')routes to the S3 provider.write_file('/reports/summary.md')routes to the Google Cloud Storage provider.- Sandbox commands use the same paths when each sandbox mount succeeds.
The composite strips the mount prefix before passing the remaining path to its provider. Mount paths can't be nested, so the same composite can't contain both /data and /data/archive.
Without a sandboxDirect link to Without a sandbox
You can configure mounts without a sandbox. Mastra still creates the CompositeFilesystem, and all file tools work with mount-prefixed paths. The agent receives no command or process tools because no sandbox is configured.
Manual compositionDirect link to Manual composition
You can also create a CompositeFilesystem yourself and pass it through filesystem for path routing without automatic sandbox mount wiring:
import { CompositeFilesystem, LocalFilesystem, Workspace } from '@mastra/core/workspace'
import { S3Filesystem } from '@mastra/s3'
const filesystem = new CompositeFilesystem({
mounts: {
'/local': new LocalFilesystem({ basePath: './data' }),
'/archive': new S3Filesystem({
bucket: 'agent-archive',
region: 'us-east-1',
}),
},
})
const workspace = new Workspace({ filesystem })
Use manual composition when another part of your application needs the composite as a filesystem provider. For normal sandbox mounting, the mounts option performs the same routing setup with less configuration.
Mount availabilityDirect link to Mount availability
File tools and composite routing work without a sandbox mount. When a remote sandbox and filesystem provider support mounting, mounts automatically uses FUSE to make the files visible to commands. LocalSandbox uses symlinks instead.
Built-in sandbox mounting currently includes:
| Sandbox backend | Filesystem providers |
|---|---|
LocalSandbox | LocalFilesystem |
| E2B | Amazon S3, Google Cloud Storage, Azure Blob Storage |
| Daytona | Amazon S3, Google Cloud Storage, Azure Blob Storage |
| Blaxel | Amazon S3, Google Cloud Storage |
Remote mounts may require s3fs, gcsfuse, or blobfuse2 inside the sandbox. Some backends install missing software during startup, which can require network access and additional startup time. Other combinations require an onMount hook or provider-specific setup.
If a sandbox mount is unavailable or fails, the workspace remains usable. File tools continue to access the provider through its SDK, but commands can't see that path. Mastra describes these providers to the agent as available through file tools only.
Filesystems per user or threadDirect link to Filesystems per user or thread
The filesystem option accepts a resolver when storage should vary by request, user, role, or tenant:
const workspace = new Workspace({
filesystem: ({ requestContext }) => {
const userId = requestContext.get('user-id') as string
return new S3Filesystem({
bucket: process.env.S3_BUCKET!,
region: process.env.S3_REGION!,
prefix: `users/${userId}`,
})
},
})
Each user gets a separate filesystem view, and file tools resolve the provider from the request context automatically.
mounts doesn't accept a resolver and can't be combined with a sandbox resolver. When each user or thread needs separate storage inside a separate sandbox, create and mount the provider inside the sandbox resolver. See Sandboxes per user or thread.
Policies and containmentDirect link to Policies and containment
Use individual constants under WORKSPACE_TOOLS.FILESYSTEM, such as WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE, to configure each file tool. Set approval globally or per tool. Configure read-before-write and output limits on individual filesystem tool entries. See the filesystem tool configuration reference.
LocalFilesystem contains access within basePath by default. Use allowedPaths when the agent needs specific directories outside that root:
const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './knowledge-base',
allowedPaths: ['../shared-policies'],
}),
})
Containment applies to filesystem operations, including file tools and search indexing. It doesn't restrict shell commands.
Set readOnly: true when the agent should use files without changing them. For a static provider, Mastra removes write-related file tools.
With a filesystem resolver, write tools remain registered because the provider isn't known until the request runs. The provider rejects write attempts at runtime.
For LocalFilesystem entries in a composite, keep contained: true, which is the default. Set contained: false only when unrestricted host filesystem access is intentional.