AppleContainerSandbox
Executes commands inside local OCI Linux containers through Apple's container CLI. The provider starts a long-lived container and uses container exec for workspace commands.
For interface details, see WorkspaceSandbox interface.
InstallationDirect link to Installation
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/apple-container
pnpm add @mastra/apple-container
yarn add @mastra/apple-container
bun add @mastra/apple-container
Requires an Apple silicon Mac running macOS 26 or newer with Apple's container CLI installed. Start the container system before using the provider:
container system start
UsageDirect link to Usage
Add an AppleContainerSandbox to a workspace and assign it to an agent:
import { Agent } from '@mastra/core/agent'
import { Workspace } from '@mastra/core/workspace'
import { AppleContainerSandbox } from '@mastra/apple-container'
const workspace = new Workspace({
sandbox: new AppleContainerSandbox({
image: 'node:22-slim',
volumes: {
'/Users/me/project': '/workspace',
},
workingDir: '/workspace',
}),
})
const agent = new Agent({
id: 'dev-agent',
name: 'Dev Agent',
instructions: 'You are a coding assistant working in this workspace.',
model: 'anthropic/claude-sonnet-4-6',
workspace,
})
const response = await agent.generate('Run `node --version`.')
console.log(response.text)
Constructor parametersDirect link to Constructor parameters
id?:
name?:
image?:
command?:
env?:
volumes?:
mounts?:
network?:
publishedPorts?:
publishedSockets?:
cpus?:
memory?:
platform?:
arch?:
os?:
rosetta?:
readonlyRootfs?:
ssh?:
init?:
virtualization?:
capAdd?:
capDrop?:
tmpfs?:
dns?:
dnsSearch?:
noDns?:
labels?:
workingDir?:
timeout?:
deleteOnDestroy?:
containerBinary?:
instructions?:
PropertiesDirect link to Properties
id:
name:
provider:
status:
containerId:
Environment variablesDirect link to Environment variables
Set environment variables at the container level with env. Per-command environment variables can also be passed through executeCommand options:
const sandbox = new AppleContainerSandbox({
image: 'node:22-slim',
env: {
NODE_ENV: 'development',
},
})
await sandbox.executeCommand('node', ['-e', 'console.log(process.env.TASK_ID)'], {
env: { TASK_ID: '42' },
})
Bind mountsDirect link to Bind mounts
Mount host directories into the container using the volumes option:
const sandbox = new AppleContainerSandbox({
image: 'node:22-slim',
volumes: {
'/Users/me/project': '/workspace/project',
'/Users/me/.npm': '/root/.npm',
},
})
Bind mounts are applied at container creation time. The host paths must exist before the sandbox starts.
Resource and platform optionsDirect link to Resource and platform options
Apple container CLI options can be passed through the constructor:
const sandbox = new AppleContainerSandbox({
image: 'node:22-slim',
volumes: {
'/Users/me/project': '/workspace',
},
cpus: 2,
memory: '2G',
platform: 'linux/arm64',
readonlyRootfs: true,
tmpfs: ['/tmp'],
})
These options are only applied when a new container is created. If the sandbox reconnects to an existing container with the same name, destroy and recreate the sandbox to apply changed runtime options.
Apple --tmpfs accepts container paths only, such as /tmp; it does not accept Docker-style option specs like /tmp:rw,size=256m.
When readonlyRootfs is enabled, make sure workingDir points to a path supplied by the image, a bind mount, or a writable tmpfs.
Security modelDirect link to Security model
AppleContainerSandbox runs local containers through the host Apple container service. Treat constructor options as trusted server-side configuration:
volumes,mounts, andpublishedSocketscan expose host paths to containerized code.publishedPortscan expose in-container services on the host or network; bind to127.0.0.1when only local access is intended.sshforwards the host SSH agent socket.capAddandvirtualizationcan expand what containerized code can do.containerBinaryis a constructor-only escape hatch for trusted code and is not part of the serializable editor provider schema.
Use the narrowest mounts and capabilities your workload needs. Existing containers are only reconnected when they carry Mastra ownership labels for the sandbox ID. Containers created by this provider also include a config-hash label; when that label is present, reconnect fails if immutable runtime options such as image, command, mounts, ports, capabilities, or working directory changed.
LimitationsDirect link to Limitations
AppleContainerSandbox implements foreground workspace command execution with executeCommand(). It does not yet expose a SandboxProcessManager for background processes or LSP sessions.
Command timeouts are enforced inside the container so timed-out commands are cleaned up by the container runtime. Abort signals cancel the host CLI wait path and should not be used as a substitute for command timeouts when in-container cleanup matters.
ReconnectionDirect link to Reconnection
AppleContainerSandbox reconnects by inspecting a container with the configured name. When start() is called:
- A running container is reused.
- A stopped container is restarted.
- A missing container is created from the configured image.
- A container with the configured name but without matching Mastra ownership labels fails instead of being managed.
- A Mastra-owned container with a config-hash label that does not match immutable runtime options fails instead of being reused.
const sandbox = new AppleContainerSandbox({ id: 'persistent-sandbox' })
await sandbox.start()
const sandbox2 = new AppleContainerSandbox({ id: 'persistent-sandbox' })
await sandbox2.start()
Editor providerDirect link to Editor provider
Register the provider with MastraEditor to hydrate stored sandbox configs:
import { MastraEditor } from '@mastra/editor'
import { appleContainerSandboxProvider } from '@mastra/apple-container'
const editor = new MastraEditor({
sandboxes: {
[appleContainerSandboxProvider.id]: appleContainerSandboxProvider,
},
})