Workspaces

Trust: ★★★☆☆ (0.90) · 0 validations · developer_reference

Published: 2026-05-10 · Source: crawler_authoritative

Tình huống

Mastra documentation for configuring workspaces that give agents persistent environments for file storage, command execution, and code inspection.

Insight

A Mastra workspace provides agents with a persistent environment supporting five main features: Filesystem (read, write, list, delete, copy, move, grep operations), Sandbox (shell commands and background processes), LSP inspection (hover, definition, implementation queries), Search (BM25, vector, or hybrid search), and Skills (reusable instruction sets). The Workspace class is imported from ‘@mastra/core/workspace’ and accepts filesystem, sandbox, skills, mounts, lsp, and tools configuration options. Workspaces are available starting from ‘@mastra/[email protected]’. When assigned to an agent, Mastra automatically includes the corresponding tools in the agent’s toolset. The filesystem option supports providers like LocalFilesystem for local storage and S3Filesystem for cloud storage. The sandbox option supports LocalSandbox for local command execution and E2BSandbox for cloud sandboxes. The mounts configuration creates a CompositeFilesystem that routes operations based on path prefix, enabling FUSE-mounting of cloud storage (S3, GCS) into sandboxes. Filesystem and mounts are mutually exclusive—use filesystem for a single provider without sandbox, or mounts when combining cloud storage with a sandbox. The filesystem option also accepts a resolver function for dynamic per-request storage, useful for multi-tenant applications where each request gets a different storage root or permissions. The tools configuration controls which tools are enabled and their behavior, with options for enabled, requireApproval, requireReadBeforeWrite, name, and maxOutputTokens. Tool options can be dynamic functions receiving requestContext, workspace, or args. Workspace tools automatically truncate output using line-based tail (last 200 lines default) and token-based limit (2000 tokens default). ANSI escape codes are stripped automatically. Read-before-write enforcement works at two layers: tool layer checks modification time and filesystem layer compares expectedMtime at write time.

Hành động

To create a workspace, import Workspace and provider classes from ‘@mastra/core/workspace’, instantiate with desired features, then assign to either the Mastra global instance or individual agents. For a global workspace that all agents inherit: create a Workspace instance with filesystem and/or sandbox providers, then pass it to the Mastra constructor. For agent-level workspace: create a Workspace instance with custom basePath, then assign it to the agent’s workspace property. Configuration patterns include: (1) filesystem + sandbox for local development with both file tools and execute_command; (2) mounts + sandbox for cloud storage accessible inside a cloud sandbox using path-based routing; (3) filesystem only when agents only need file operations; (4) sandbox only when agents only need command execution; (5) filesystem with resolver function for per-request dynamic storage. Tool configuration uses WORKSPACE_TOOLS constants to enable/disable individual tools, set requireApproval per-tool, configure name remapping, and set maxOutputTokens limits. Call workspace.init() optionally to pre-provision resources for standalone scripts or tests, though most providers initialize on first operation. The skills array specifies paths to directories containing skill definitions.

Kết quả

Agents receive the configured tools in their toolset, enabling file operations, command execution, LSP inspection, and/or search based on workspace configuration. File tools operate against the configured storage provider, sandbox commands execute with access to mounted filesystems, and output is automatically truncated to prevent context overflow.

Điều kiện áp dụng

Available in @mastra/[email protected] or later. filesystem and mounts options are mutually exclusive. Tool names must be unique—duplicate names throw an error.


Nội dung gốc (Original)

Workspaces

Added in: @mastra/[email protected]

A Mastra workspace gives agents a persistent environment for storing files and executing commands. Agents use workspace tools to read and write files, run shell commands, and search indexed content.

A workspace supports the following features:

  • Filesystem: File storage (read, write, list, delete, copy, move, grep)
  • Sandbox: Command execution (shell commands) and background processes
  • LSP inspection: Hover, definition, and implementation queries through language servers
  • Search: BM25, vector, or hybrid search over indexed content
  • Skills: Reusable instructions for agents

When to use workspaces

Use a workspace when your agent needs access to the local filesystem, shell commands, semantic code inspection, indexed search, or reusable skill instructions.

How it works

When you assign a workspace to an agent, Mastra includes the corresponding tools in the agent’s toolset. The agent can then use these tools to interact with files and execute commands.

You can create a workspace with any combination of the supported features. The agent receives only the tools relevant to what’s configured.

Usage

Creating a workspace

Create a workspace by instantiating the Workspace class with your desired features:

import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'
 
const workspace = new Workspace({
  filesystem: new LocalFilesystem({
    basePath: './workspace',
  }),
  sandbox: new LocalSandbox({
    workingDirectory: './workspace',
  }),
  skills: ['skills'],
})

The skills array specifies paths to directories containing skill definitions, see Skills.

Global workspace

Set a workspace on the Mastra instance. All agents inherit this workspace unless they define their own:

import { Mastra } from '@mastra/core'
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'
 
const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
})
 
const mastra = new Mastra({
  workspace,
})

Agent-level workspace

Assign a workspace directly to an agent to override the global workspace:

import { Agent } from '@mastra/core/agent'
import { Workspace, LocalFilesystem } from '@mastra/core/workspace'
 
const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './agent-workspace' }),
})
 
export const myAgent = new Agent({
  id: 'my-agent',
  model: 'openai/gpt-5.4',
  workspace,
})

Configuration patterns

Workspaces support several configuration patterns depending on what capabilities your agent needs. The two main building blocks are filesystem (file tools) and sandbox (command execution), with mounts as the way to bridge cloud storage into sandboxes.

Filesystem + sandbox (local)

For local development, pair a LocalFilesystem and LocalSandbox pointed at the same directory. Since both operate on the local machine, files written through the filesystem are immediately available to commands in the sandbox:

const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
  sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
})

The agent receives both file tools and execute_command. This is the simplest full-featured setup.

Mounts + sandbox (cloud storage)

When you need cloud storage accessible inside a sandbox, use mounts. This FUSE-mounts the cloud filesystem into the sandbox so commands can read and write files at the mount path:

const workspace = new Workspace({
  mounts: {
    '/data': new S3Filesystem({
      bucket: 'my-bucket',
      region: 'us-east-1',
      accessKeyId: process.env.AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    }),
    '/skills': new GCSFilesystem({
      bucket: 'agent-skills',
    }),
  },
  sandbox: new E2BSandbox({ id: 'dev-sandbox' }),
})

Under the hood, mounts creates a CompositeFilesystem that routes file tool operations to the correct provider based on path prefix. Commands in the sandbox access the mounted paths directly (e.g., ls /data).

You can mount multiple providers at different paths. Each mount path must be unique and non-overlapping.

Note: filesystem and mounts are mutually exclusive — you can’t use both in the same workspace. Use filesystem for a single provider without a sandbox, or mounts when you need to combine cloud storage with a sandbox.

Filesystem only

Use a single filesystem when agents only need to read and write files. No command execution is available.

const workspace = new Workspace({
  filesystem: new S3Filesystem({
    bucket: 'my-bucket',
    region: 'us-east-1',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  }),
})

The agent receives file tools (read_file, write_file, list_directory, grep, etc.) that operate directly against the storage provider.

Sandbox only

Use a single sandbox when agents only need to execute commands. No file tools are added.

const workspace = new Workspace({
  sandbox: new E2BSandbox({ id: 'dev-sandbox' }),
})

The agent receives the execute_command tool.

Dynamic filesystem (per-request)

Pass a resolver function to filesystem to return a different filesystem per request. This is useful for multi-tenant applications or multi-role agents where each request needs a different storage root or different permissions.

const workspace = new Workspace({
  filesystem: ({ requestContext }) => {
    const role = requestContext.get('agent-role') || 'guest'
    return new LocalFilesystem({
      basePath: `/workspaces/${role}`,
      readOnly: role !== 'admin',
    })
  },
})

One workspace instance serves all requests. The resolver runs at tool execution time, so each request gets its own filesystem. See dynamic filesystem for details.

Which pattern should I use?

ScenarioPattern
Local development with files and commandsfilesystem + sandbox (both local, same directory)
Cloud storage accessible inside a cloud sandboxmounts + sandbox
Multiple cloud providers in one sandboxmounts + sandbox (one mount per provider)
Agent reads/writes files, no command execution neededfilesystem only
Agent runs commands, no file tools neededsandbox only
Multi-role or multi-tenant agent with per-request storagefilesystem with resolver function

Tool configuration

Configure tool behavior through the tools option on the workspace. This controls which tools are enabled and how they behave.

import { Workspace, LocalFilesystem, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'
 
const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
  sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
  tools: {
    // Global defaults
    enabled: true,
    requireApproval: false,
 
    // Per-tool overrides
    [WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: {
      requireApproval: true,
      requireReadBeforeWrite: true,
    },
    [WORKSPACE_TOOLS.FILESYSTEM.DELETE]: {
      enabled: false,
    },
    [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
      requireApproval: true,
    },
  },
})

Tool options

OptionTypeDescription
enabledboolean | (context) => booleanWhether the tool is available (default: true). When a function, evaluated at tool-listing time.
requireApprovalboolean | (context) => booleanWhether the tool requires user approval before execution (default: false). When a function, evaluated at execution time with access to args.
requireReadBeforeWriteboolean | (context) => booleanFor write tools: require reading the file first (default: false). When a function, evaluated at execution time with access to args.
namestringCustom name for the tool. Replaces the default mastra_workspace_* name.
maxOutputTokensnumberMaximum tokens for tool output (default: 2000). Output exceeding this limit is truncated using tiktoken.

Dynamic tool configuration

Tool options that accept functions receive a context object and return a boolean. This enables context-aware tool behavior.

const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
  tools: {
    // Dynamic enabled: disable command execution unless explicitly allowed
    [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
      enabled: async ({ requestContext }) => {
        return requestContext['allowExecution'] === 'true'
      },
    },
 
    // Dynamic requireApproval: only require approval for protected paths
    [WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: {
      requireApproval: async ({ args }) => {
        return (args.path as string).startsWith('/protected')
      },
      requireReadBeforeWrite: true,
    },
  },
})

Functions for enabled receive { requestContext, workspace }. Functions for requireApproval and requireReadBeforeWrite also receive args since they are evaluated when the tool is called.

Tool name remapping

Rename workspace tools to match the conventions your agent expects. The config key remains the original WORKSPACE_TOOLS constant — only the exposed name changes.

import { Workspace, LocalFilesystem, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'
 
const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
  sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
  lsp: true,
  tools: {
    [WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: { name: 'view' },
    [WORKSPACE_TOOLS.FILESYSTEM.GREP]: { name: 'search_content' },
    [WORKSPACE_TOOLS.FILESYSTEM.LIST_FILES]: { name: 'find_files' },
    [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: { name: 'execute_command' },
    [WORKSPACE_TOOLS.LSP.LSP_INSPECT]: { name: 'lsp_inspect' },
  },
})

The agent sees view, search_content, find_files, execute_command, and lsp_inspect instead of the default mastra_workspace_* names. Tool names must be unique — duplicate names or conflicts with other default names throw an error.

LSP inspection

Enable lsp on a workspace to add semantic code inspection through language servers. This adds the mastra_workspace_lsp_inspect tool by default, which can return hover information, definition locations, and implementations for a symbol at a specific cursor position.

See LSP inspection for configuration, examples, and tool name remapping.

Output truncation

Workspace tools automatically truncate large outputs to avoid exceeding LLM context limits. Two layers of truncation apply:

  1. Line-based tail: Command output is limited to the last 200 lines by default (configurable per-command via the tail parameter)
  2. Token-based limit: Tool output is capped at 2000 tokens by default

Set maxOutputTokens per tool to adjust the token limit:

const workspace = new Workspace({
  // ...
  tools: {
    [WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
      maxOutputTokens: 5000,
    },
  },
})

ANSI escape codes (colors, cursor sequences) are automatically stripped from command output before it reaches the model.

Read-before-write

When requireReadBeforeWrite is enabled on write tools, agents must read a file before writing to it. This prevents overwriting files the agent hasn’t seen:

  • New files: Can be written without reading (they don’t exist yet)
  • Existing files: Must be read first
  • Externally modified files: If a file changed since the agent read it, the write fails

File write safety is enforced at two layers:

  1. Tool layer: Before a write tool runs, the read tracker checks whether the file was modified since it was last read. If it was, the tool throws a FileReadRequiredError.
  2. Filesystem layer: At write time, writeFile() compares the file’s current modification time against the expected value (passed via expectedMtime in write options). If they don’t match, it throws a StaleFileError. This catches external modifications (for example, an editor saving the file) that happen between the tool-level check and the actual write.

When requireReadBeforeWrite is enabled, workspace tools pass the recorded modification time through automatically. You can also use expectedMtime directly when calling filesystem.writeFile() outside of tools:

const stat = await filesystem.stat('/docs/file.md')
// ... later ...
await filesystem.writeFile('/docs/file.md', newContent, {
  expectedMtime: stat.modifiedAt,
})

Initialization

Calling init() is optional in most cases—some providers initialize on first operation. Call init() manually when using a workspace outside of Mastra (standalone scripts, tests) or when you need to pre-provision resources before the first agent interaction.

import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'
 
const workspace = new Workspace({
  filesystem: new LocalFilesystem({ basePath: './workspace' }),
  sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
})
 
// Optional: pre-create directories and sandbox before first use
await workspace.init()

What init() does

Initialization runs setup logic for each configured provider:

  • LocalFilesystem: Creates the base directory if it doesn’t exist
  • LocalSandbox: Creates the working directory
  • Search (if configured): Indexes files from autoIndexPaths, see Search and Indexing

External providers may perform additional setup like establishing connections or authenticating.

Liên kết

Xem thêm: