Introducing Filesystem Mounts for Mastra Workspaces

Read and write to multiple filesystems using the same file interface.

Paul ScanlonPaul Scanlon·

Sep 8, 2026

·

3 min read

You can now use multiple filesystems from a single Mastra workspace with mounts. Read from restricted storage environments and write to the filesystems your team already use. Mastra supports a number of remote filesystems letting you mix-and-match to suit your needs.

By configuring multiple filesystems, your agents, tools, and workflows can read from multiple sources, combine the data, and write to a destination through the same file interface.

Before mounts, a Mastra workspace attached one filesystem at a time. Reading from one provider and writing to another meant hand-rolling the routing, or calling underlying SDKs directly. Now, all filesystems are available through the mountPath, making it easier to read and write across multiple filesystems.

Under the hood, mounts builds a CompositeFilesystem that routes each read or write to the correct provider. With a sandbox configured, Mastra also mounts each provider with FUSE (Filesystem in Userspace). Scripts and CLI tools inside the sandbox then work with the mounted files directly.

Get started

Install the filesystem providers. This example uses Amazon S3 and Google Drive:

GNU BashTerminal
npm install @mastra/s3 @mastra/google-drive
note
Requires @mastra/core@1.51.0 or later, added in PR #12851.

Create a workspace with a mount for each filesystem:

TypeScriptsrc/mastra/workspaces/s3-google-drive-workspace.ts
import { Workspace } from "@mastra/core/workspace";
import { S3Filesystem } from "@mastra/s3";
import { GoogleDriveFilesystem } from "@mastra/google-drive";
 
export const s3GoogleDriveWorkspace = new Workspace({
  id: "s3-google-drive-workspace",
  mounts: {
    "/data": new S3Filesystem({
      bucket: process.env.S3_BUCKET!,
      region: process.env.AWS_REGION!,
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
    }),
    "/reports": new GoogleDriveFilesystem({
      folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
      serviceAccount: {
        clientEmail: process.env.GOOGLE_DRIVE_CLIENT_EMAIL!,
        privateKey: process.env.GOOGLE_DRIVE_PRIVATE_KEY!
      }
    })
  }
});

Register the workspace on your main Mastra instance:

TypeScriptsrc/mastra/index.ts
import { Mastra } from "@mastra/core/mastra";
import { s3GoogleDriveWorkspace } from "./workspaces/s3-google-drive-workspace";
 
export const mastra = new Mastra({
  // ...
  workspace: s3GoogleDriveWorkspace
});

Accessing a filesystem from a workflow step or tool's execute function works the same way. The mountPath routes reads or writes to the configured filesystem.

TypeScriptsrc/mastra/workflows/customer-voice-workflow.ts
const readInAppFeedbackStep = createStep({
  id: "read-in-app-feedback",
  // ...
  execute: async ({ inputData, mastra }) => {
    const fs = mastra?.getWorkspace()?.filesystem;
    const mountPath = "/data"; // S3Filesystem
    const entries = await fs.readdir(`${mountPath}/${inputData.year}/${inputData.month}/in-app-feedback`);
    // ...
  }
});
 
const saveToDriveStep = createStep({
  id: "save-to-drive",
  // ...
  execute: async ({ inputData, mastra }) => {
    const fs = mastra?.getWorkspace()?.filesystem;
    const mountPath = "/reports"; // GoogleDriveFilesystem
    await fs.writeFile(`${mountPath}/${inputData.filename}`, buffer);
    // ...
  }
});

Errors

Errors from the underlying provider surface as typed exceptions you can catch:

import { FileNotFoundError } from "@mastra/core/workspace";
 
// ...
 
try {
  const entries = await fs.readdir(mountPath);
  // ...
} catch (error) {
  if (error instanceof FileNotFoundError) {
    // handle a missing path
  }
  throw error;
}

onMount

When using a sandbox, the onMount callback fires for every configured filesystem letting you inspect the details for each one:

TypeScriptsrc/mastra/workspaces/s3-google-drive-workspace.ts
import { LocalSandbox, Workspace } from "@mastra/core/workspace";
 
export const s3GoogleDriveWorkspace = new Workspace({
  // ...
  mounts: {
    /* ... */
  },
  sandbox: new LocalSandbox({ workingDirectory: "workspace" }),
  onMount: async ({ filesystem, mountPath, config }) => {
    if (!config) {
      console.log(`no mount config for ${filesystem.name} at ${mountPath}`);
      return;
    }
    console.log("mountPath:", mountPath);
    console.log("filesystem:", filesystem.name);
    console.log("config:", config.type);
  }
});

onMount only fires when a sandbox is invoked. Reads and writes to filesystems typically don't require a sandbox.

For more information and full configuration options, see:

Share on X or LinkedIn
Paul Scanlon
Paul ScanlonTechnical Product Marketing Manager

Paul Scanlon sits between Developer Education and Product Marketing at Mastra. Previously, he was a Technical Product Marketing Manager at Neon and worked in Developer Relations at Gatsby, where he created educational content and developer experiences.

All articles by Paul Scanlon