# FilesSDKFilesystem Stores files in any storage backend supported by [FilesSDK](https://files-sdk.dev) — a unified abstraction over S3, Cloudflare R2, Google Cloud Storage, Azure Blob, Vercel Blob, MinIO, the local filesystem, and more. > **Info:** For interface details, see [WorkspaceFilesystem Interface](https://mastra.ai/reference/workspace/filesystem). Use `FilesSDKFilesystem` when you want a single adapter that can target multiple storage backends with the same code. Swap the underlying driver without changing the workspace setup. If you only target one backend and want first-class options for that backend, prefer the dedicated provider (for example [`S3Filesystem`](https://mastra.ai/reference/workspace/s3-filesystem) or [`GCSFilesystem`](https://mastra.ai/reference/workspace/gcs-filesystem)). ## Installation **npm**: ```bash npm install @mastra/files-sdk files-sdk ``` **pnpm**: ```bash pnpm add @mastra/files-sdk files-sdk ``` **Yarn**: ```bash yarn add @mastra/files-sdk files-sdk ``` **Bun**: ```bash bun add @mastra/files-sdk files-sdk ``` `files-sdk` is a peer dependency you configure with the adapter you want to use. ## Usage Create a `Files` instance from FilesSDK with the adapter of your choice, then pass it to `FilesSDKFilesystem`: ```typescript import { Agent } from '@mastra/core/agent' import { Workspace } from '@mastra/core/workspace' import { FilesSDKFilesystem } from '@mastra/files-sdk' import { Files } from 'files-sdk' import { s3 } from 'files-sdk/s3' const files = new Files({ adapter: s3({ bucket: 'my-bucket', region: 'us-east-1', }), }) const workspace = new Workspace({ filesystem: new FilesSDKFilesystem({ files }), }) const agent = new Agent({ name: 'file-agent', model: 'anthropic/claude-opus-4-6', workspace, }) ``` ### Swapping adapters The same `FilesSDKFilesystem` works with any FilesSDK adapter. Replace the driver factory to switch backends: ```typescript import { Files } from 'files-sdk' import { r2 } from 'files-sdk/r2' import { gcs } from 'files-sdk/gcs' import { azure } from 'files-sdk/azure' import { fs } from 'files-sdk/fs' // Cloudflare R2 const r2Files = new Files({ adapter: r2({ accountId, bucket, accessKeyId, secretAccessKey }) }) // Google Cloud Storage const gcsFiles = new Files({ adapter: gcs({ bucket, projectId }) }) // Azure Blob const azureFiles = new Files({ adapter: azure({ container, connectionString }) }) // Local filesystem (useful for tests and development) const localFiles = new Files({ adapter: fs({ root: './workspace' }) }) ``` See the [FilesSDK documentation](https://files-sdk.dev) for the full adapter catalog and configuration options. ### Read-only mounts ```typescript const filesystem = new FilesSDKFilesystem({ files, readOnly: true, }) ``` All write operations (`writeFile`, `appendFile`, `deleteFile`, `copyFile`, `moveFile`, `mkdir`, `rmdir`) throw `WorkspaceReadOnlyError` while reads succeed. ## Constructor parameters **files** (`Files`): A pre-configured FilesSDK \`Files\` instance bound to the adapter and credentials you want to use. **id** (`string`): Unique identifier for this filesystem instance. (Default: `Auto-generated`) **displayName** (`string`): Human-friendly display name for the UI. **icon** (`FilesystemIcon`): Icon identifier for the UI. **description** (`string`): Short description of this filesystem for the UI. **readOnly** (`boolean`): When true, all write operations are blocked. (Default: `false`) ## Properties **id** (`string`): Filesystem instance identifier. **name** (`string`): Provider name ('FilesSDKFilesystem'). **provider** (`string`): Provider identifier ('files-sdk'). **readOnly** (`boolean | undefined`): Whether the filesystem is in read-only mode. ## Methods `FilesSDKFilesystem` implements the [WorkspaceFilesystem interface](https://mastra.ai/reference/workspace/filesystem), providing all standard filesystem methods: - `readFile(path, options?)` - Read file contents - `writeFile(path, content, options?)` - Write content to a file - `appendFile(path, content)` - Append content to a file - `deleteFile(path, options?)` - Delete a file - `copyFile(src, dest, options?)` - Copy a file - `moveFile(src, dest, options?)` - Move or rename a file - `mkdir(path, options?)` - Create a directory (no-op for object stores) - `rmdir(path, options?)` - Remove a directory - `readdir(path, options?)` - List directory contents - `exists(path)` - Check if a path exists - `stat(path)` - Get file or directory metadata ### `init()` Initialize the filesystem. Verifies that the configured adapter can list keys with the supplied credentials. ```typescript await filesystem.init() ``` ### `getInfo()` Returns metadata about this filesystem instance. ```typescript const info = filesystem.getInfo() // { id: '...', name: 'FilesSDKFilesystem', provider: 'files-sdk', status: 'ready' } ``` ### `files` The underlying FilesSDK `Files` instance is exposed as a public property if you need to call adapter-specific APIs directly. ```typescript const url = await filesystem.files.url('reports/q3.pdf') ``` ## Object-store semantics `FilesSDKFilesystem` treats the configured backend as an object store, even when the underlying adapter is hierarchical (such as `fs`). This keeps behavior consistent across adapters: - **`mkdir`** is a no-op. Directories exist implicitly when keys with that prefix exist. - **`exists`** returns `true` only when an exact key is present as a file, or when the path is a prefix that contains at least one child key. Empty leftover directories on hierarchical adapters do not count. - **`deleteFile`** throws `FileNotFoundError` when the key does not exist, unless `{ force: true }` is passed. - **`deleteFile`** on a directory delegates to `rmdir({ recursive: true })`, matching the [`S3Filesystem`](https://mastra.ai/reference/workspace/s3-filesystem) and [`GCSFilesystem`](https://mastra.ai/reference/workspace/gcs-filesystem) behavior. - **`moveFile`** is implemented as `copyFile` followed by `deleteFile`. It is **not atomic** — if the source delete fails after a successful copy, the destination remains and the source is not removed. - **`appendFile`** is a read-modify-write operation. Concurrent appends to the same key may overwrite each other; this is inherent to object storage and not specific to FilesSDK. - **`readdir({ recursive: true })`** emits intermediate directory entries (for example, `a/b` is emitted alongside `a/b/c.txt`). ## Related - [WorkspaceFilesystem interface](https://mastra.ai/reference/workspace/filesystem) - [S3Filesystem reference](https://mastra.ai/reference/workspace/s3-filesystem) - [GCSFilesystem reference](https://mastra.ai/reference/workspace/gcs-filesystem) - [AzureBlobFilesystem reference](https://mastra.ai/reference/workspace/azure-blob-filesystem) - [Workspace overview](https://mastra.ai/docs/workspace/overview) - [FilesSDK documentation](https://files-sdk.dev)