Skip to main content

PlatformFilesystem

Stores files in a Mastra Platform workspace bucket. Each Mastra Platform environment can have one bucket, and PlatformFilesystem gives agents read, write, list, delete, and move operations against it.

Related providers: S3Filesystem for direct S3 access, LocalFilesystem for local directories.

note

For interface details, see WorkspaceFilesystem interface.

Installation
Direct link to Installation

npm install @mastra/platform-workspace

Configure the platform credentials. The access token, project ID, and bucket name fall back to environment variables, so a Mastra Platform deployment can pass zero constructor options.

MASTRA_PLATFORM_ACCESS_TOKEN=your-platform-access-token
MASTRA_PROJECT_ID=your-project-id
MASTRA_PLATFORM_BUCKET_NAME=your-bucket-name

On a Mastra Platform deployment, MASTRA_PLATFORM_ACCESS_TOKEN, MASTRA_PROJECT_ID, and MASTRA_PLATFORM_BUCKET_NAME are injected automatically, so the constructor can be called with no options. For local development, MASTRA_PLATFORM_ACCESS_TOKEN can contain an sk_ API token from your organization's settings page under API Tokens.

Usage
Direct link to Usage

Add a PlatformFilesystem to a workspace and assign it to an agent:

import { Agent } from '@mastra/core/agent'
import { Workspace } from '@mastra/core/workspace'
import { PlatformFilesystem } from '@mastra/platform-workspace'

const workspace = new Workspace({
filesystem: new PlatformFilesystem({
// accessToken, projectId, bucketName all fall back to env vars
}),
})

const agent = new Agent({
id: 'file-agent',
name: 'File Agent',
instructions: 'You are a research assistant that reads and writes reports.',
model: 'anthropic/claude-sonnet-4-6',
workspace,
})

Reading and writing files
Direct link to Reading and writing files

Object keys are percent-encoded per segment, so filenames with ?, #, %, &, +, or spaces are preserved end-to-end:

const fs = new PlatformFilesystem()

await fs.writeFile('/analyses/repo.md', markdown)
const content = await fs.readFile('/analyses/repo.md')
const entries = await fs.readdir('/analyses')
await fs.moveFile('/analyses/repo.md', '/analyses/repo-final.md')

Read-only mode
Direct link to Read-only mode

Pass readOnly: true to mount the bucket read-only. Any mutating call throws WorkspaceReadOnlyError:

const fs = new PlatformFilesystem({ readOnly: true })

await fs.readFile('/analyses/repo.md') // ok
await fs.writeFile('/analyses/repo.md', 'x') // throws WorkspaceReadOnlyError

Overwrite semantics
Direct link to Overwrite semantics

writeFile supports overwrite: false and throws FileExistsError when the destination already exists.

copyFile and moveFile always overwrite the destination. Passing overwrite: false to either method throws an error rather than silently overwriting.

Appending files
Direct link to Appending files

appendFile is a read-modify-write and isn't atomic. Concurrent appends to the same path can overwrite each other. For concurrent writers, use writeFile with distinct keys.

Constructor parameters
Direct link to Constructor parameters

accessToken?:

string
Platform access token. Falls back to the MASTRA_PLATFORM_ACCESS_TOKEN environment variable.

projectId?:

string
Platform project ID. Falls back to the MASTRA_PROJECT_ID environment variable.

bucketName?:

string
Platform bucket name to store files in. Falls back to the MASTRA_PLATFORM_BUCKET_NAME environment variable.

readOnly?:

boolean
= false
When true, all mutating calls throw WorkspaceReadOnlyError.

displayName?:

string
Human-readable name shown in workspace UIs.

description?:

string
Short description shown in workspace UIs.

icon?:

FilesystemIcon
Icon shown in workspace UIs.

instructions?:

string | ((opts: { defaultInstructions: string; requestContext?: RequestContext }) => string)
Custom instructions returned by getInstructions(). A string fully replaces the defaults; a function receives the defaults and can extend or customize them per-request.

id?:

string
= Auto-generated
Unique identifier for this filesystem instance.

fetch?:

typeof fetch
Custom fetch implementation, mainly for testing.

Properties
Direct link to Properties

id:

string
Filesystem instance identifier.

name:

string
Provider name ('PlatformFilesystem').

provider:

string
Provider identifier ('platform').

readOnly:

boolean | undefined
Whether the filesystem was mounted read-only.

Errors
Direct link to Errors

Filesystem-specific errors match the standard workspace error types:

  • FileNotFoundError: The path doesn't exist. Thrown by readFile, stat, and deleteFile (unless force: true is set).
  • FileExistsError: writeFile was called with overwrite: false and the destination already exists.
  • WorkspaceReadOnlyError: A mutating call was made on a read-only filesystem.

Other Platform API failures raise PlatformApiError. Structured { error: { message, type } } responses are parsed into .code (machine-readable kind) and .proxyMessage (human string):

import { FileNotFoundError } from '@mastra/core/workspace'
import { PlatformApiError } from '@mastra/platform-workspace'

try {
await fs.readFile('/missing.txt')
} catch (err) {
if (err instanceof FileNotFoundError) {
// handle missing file
} else if (err instanceof PlatformApiError) {
if (err.code === 'authentication_error') {
// refresh token
}
console.error(err.status, err.code, err.proxyMessage)
}
}

FileNotFoundError, FileExistsError, and WorkspaceReadOnlyError are re-exports of the standard workspace error types from @mastra/core/workspace. PlatformApiError is specific to @mastra/platform-workspace.

code and proxyMessage are undefined when the response body isn't JSON, for example an HTML 502 from a load balancer.