@mastra/core@1.12.0

mastra-ai/mastra@mastra/core@1.12.0Mar 16, 2026by PaulieScanlon

AI Summary

Added a Cloudflare Durable Objects storage adapter, fixed workspace filesystem path resolution to match real filesystem semantics, and improved observability tracing for MCP tools and agent workflows.

Key Highlights

  • Cloudflare Durable Objects Storage Adapter with SQLite persistence.
  • Workspace filesystem path resolution: absolute paths now resolve to real locations.
  • Improved observability: Dedicated `MCP_TOOL_CALL` span type.
  • More reliable agent loops with token-based message pruning.

Breaking Changes

  • `LocalFilesystem` no longer treats absolute paths as workspace-relative.
  • `ProcessHandle.pid` changed from `number` to `string`.

New Features

  • Cloudflare Durable Objects adapter
  • MCP tool call span type with server metadata
  • Token-based pruning to prevent exponential growth
  • Trace continuity preservation for workflow suspend/resume

Full Release Notes

## Highlights

### Cloudflare Durable Objects Storage Adapter
`@mastra/cloudflare` adds a new Durable Objects–backed storage implementation (in addition to KV), with SQLite persistence, batch operations, and table/column validation—enabling more robust stateful storage on Cloudflare.

### Workspace Filesystem Path Resolution Now Matches Real Filesystem Semantics
`LocalFilesystem` no longer treats absolute paths like `/file.txt` as workspace-relative; absolute paths now resolve to real filesystem locations (with containment checks), relative paths resolve against `basePath`, and `~/` expands to the home directory.

### Improved Observability for MCP Tooling and Agent/Workflow Execution
MCP tool calls are now traced with a dedicated `MCP_TOOL_CALL` span type (with server name/version metadata), Studio adds MCP-specific timeline styling, processor-triggered aborts are fully visible in traces, and workflow suspend/resume now preserves trace continuity under the original span.

### More Reliable Agent Loops and Token Budgeting in Multi-step Runs
Fixes include the agent loop continuing correctly when `onIterationComplete` returns `continue: true`, and preventing exponential token growth by running token-based message pruning at every step (including tool call continuations).

### Sandbox & Workspace Extensibility via Provider-specific Getters and String PIDs
Sandbox process IDs are now string-based (`ProcessHandle.pid: string`) to support session IDs across providers, and sandboxes/filesystems expose underlying SDK instances via new provider-specific getters (e.g., `sandbox.daytona`, `sandbox.blaxel`, `filesystem.client` for S3, `filesystem.storage/bucket` for GCS).

### Breaking Changes
- `LocalFilesystem` no longer treats absolute paths (e.g. `/src/index.ts`) as `basePath`-relative; update callers to pass relative paths when targeting the workspace.
- `ProcessHandle.pid` changed from `number` to `string`; update any code that assumes numeric PIDs (including `processes.get(...)`).

## Changelog

### [@mastra/core@1.12.0](https://github.com/mastra-ai/mastra/blob/@mastra/core@1.12.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/core/CHANGELOG.md)
#### Minor Changes

- MCP tool calls now use `MCP_TOOL_CALL` span type instead of `TOOL_CALL` in traces. `CoreToolBuilder` detects `mcpMetadata` on tools and creates spans with MCP server name, version, and tool description attributes. ([#13274](https://github.com/mastra-ai/mastra/pull/13274))

- **Absolute paths now resolve to real filesystem locations instead of being treated as workspace-relative.** ([#13804](https://github.com/mastra-ai/mastra/pull/13804))

  Previously, `LocalFilesystem` in contained mode treated absolute paths like `/file.txt` as shorthand for `basePath/file.txt` (a "virtual-root" convention). This could silently resolve paths to unexpected locations — for example, `/home/user/.config/file.txt` would resolve to `basePath/home/user/.config/file.txt` instead of the real path.

  Now:
  - **Absolute paths** (starting with `/`) are real filesystem paths, subject to containment checks
  - **Relative paths** (e.g., `file.txt`, `src/index.ts`) resolve against `basePath`
  - **Tilde paths** (e.g., `~/Documents`) expand to the home directory

  ### Migration

  If your code passes paths like `/file.txt` to workspace filesystem methods expecting them to resolve relative to `basePath`, change them to relative paths:

  ```ts
  // Before
  await filesystem.readFile('/src/index.ts');

  // After
  await filesystem.readFile('src/index.ts');
  ```

  Also fixed:
  - `allowedPaths` resolving against the working directory instead of `basePath`, causing unexpected permission errors when `basePath` differed from `cwd`
  - Permission errors when accessing paths under `allowedPaths` directories that don't exist yet (e.g., during skills discovery)

- Changed `ProcessHandle.pid` type from `number` to `string` to support sandbox providers that use non-numeric process identifiers (e.g., session IDs). ([#13591](https://github.com/mastra-ai/mastra/pull/13591))

  **Before:**

  ```typescript
  const handle = await sandbox.processes.spawn('node server.js');
  handle.pid; // number
  await sandbox.processes.get(42);
  ```

  **After:**

  ```typescript
  const handle = await sandbox.processes.spawn('node server.js');
  handle.pid; // string (e.g., '1234' for local, 'session-abc' for Daytona)
  await sandbox.processes.get('1234');
  ```

#### Patch Changes

- Added a `mastra/<version>` User-Agent header to all provider API requests (OpenAI, Anthropic, Google, Mistral, Groq, xAI, DeepSeek, and others) across models.dev, Netlify, and Azure gateways for better traffic attribution. ([#13087](https://github.com/mastra-ai/mastra/pull/13087))

- Update provider registry and model documentation with latest models and providers ([`9cede11`](https://github.com/mastra-ai/mastra/commit/9cede110abac9d93072e0521bb3c8bcafb9fdadf))

- Fixed processor-triggered aborts not appearing in traces. Processor spans now include abort details (reason, retry flag, metadata) and agent-level spans capture the same information when an abort short-circuits the agent run. This makes guardrail and processor aborts fully visible in tracing dashboards. ([#14038](https://github.com/mastra-ai/mastra/pull/14038))

- Fix agent loop not continuing when `onIterationComplete` returns `continue: true` ([#14170](https://github.com/mastra-ai/mastra/pull/14170))

- Fixed exponential token growth during multi-step agent workflows by implementing `processInputStep` on `TokenLimiterProcessor` and removing the redundant `processInput` method. Token-based message pruning now runs at every step of the agentic loop (including tool call continuations), keeping the in-memory message list within budget before each LLM call. Also refactored Tiktoken encoder to use the shared global singleton from `getTiktoken()` instead of creating a new instance per processor. ([#13929](https://github.com/mastra-ai/mastra/pull/13929))

- Sub-agents with `defaultOptions.memory` configurations were having their memory settings overridden when called as tools from a parent agent. The parent unconditionally passed its own `memory` option (with newly generated thread/resource IDs), which replaced the sub-agent's intended memory configuration due to shallow object merging. ([#11561](https://github.com/mastra-ai/mastra/pull/11561))

  This fix checks if the sub-agent has its own `defaultOptions.memory` before applying parent-derived memory settings. Sub-agents without their own memory config continue to receive parent-derived IDs as a fallback.

  No code changes required for consumers - sub-agents with explicit `defaultOptions.memory` will now work correctly when used via the `agents: {}` option.

- Fixed listConfiguredInputProcessors() and listConfiguredOutputProcessors() returning a combined workflow instead of individual processors. Previously, these methods wrapped all configured processors into a single committed workflow, making it impossible to inspect or look up processors by ID. Now they return the raw flat array of configured processors as intended. ([#14158](https://github.com/mastra-ai/mastra/pull/14158))

- `fetchWithRetry` now backs off in sequence 2s → 4s → 8s and then caps at 10s. ([#14159](https://github.com/mastra-ai/mastra/pull/14159))

- Preserve trace continuity across workflow suspend/resume for workflows run by the default engine, so resumed workflows appear as children of the original span in tracing tools. ([#12276](https://github.com/mastra-ai/mastra/pull/12276))

### [@mastra/blaxel@0.2.0](https://github.com/mastra-ai/mastra/blob/@mastra/blaxel@0.2.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/workspaces/blaxel/CHANGELOG.md)
#### Minor Changes

- Added provider-specific `blaxel` getter to access the underlying Blaxel `SandboxInstance` directly. Deprecated the generic `instance` getter in favor of the new `blaxel` getter for better IDE discoverability and consistency with other sandbox providers. ([#14166](https://github.com/mastra-ai/mastra/pull/14166))

  ```typescript
  // Before
  const blaxelSandbox = sandbox.instance;

  // After
  const blaxelSandbox = sandbox.blaxel;
  ```

#### Patch Changes

- Use provider-native string process IDs directly as `ProcessHandle.pid`, removing the previous `parseInt()` workaround. ([#13591](https://github.com/mastra-ai/mastra/pull/13591))

  ```typescript
  const handle = await sandbox.processes.spawn('node server.js');
  handle.pid; // string — the Blaxel SDK's native process ID
  ```

### [@mastra/cloudflare@1.3.0](https://github.com/mastra-ai/mastra/blob/@mastra/cloudflare@1.3.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/stores/cloudflare/CHANGELOG.md)
#### Minor Changes

- feat: add Cloudflare Durable Objects storage adapter ([#12366](https://github.com/mastra-ai/mastra/pull/12366))

  Adds a new Durable Objects-based storage implementation alongside the existing KV store. Includes SQL-backed persistence via DO's SQLite storage, batch operations, and proper table/column validation.

#### Patch Changes

### [@mastra/cloudflare-d1@1.0.3](https://github.com/mastra-ai/mastra/blob/@mastra/cloudflare-d1@1.0.3//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/stores/cloudflare-d1/CHANGELOG.md)
#### Patch Changes

- Fixed D1 listMessages returning empty results when using semantic recall with perPage=0 and many include targets, by batching UNION ALL queries to avoid SQLite's compound SELECT limit ([#14117](https://github.com/mastra-ai/mastra/pull/14117))

### [@mastra/daytona@0.2.0](https://github.com/mastra-ai/mastra/blob/@mastra/daytona@0.2.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/workspaces/daytona/CHANGELOG.md)
#### Minor Changes

- Added provider-specific `daytona` getter to access the underlying Daytona `Sandbox` instance directly. Deprecated the generic `instance` getter in favor of the new `daytona` getter for better IDE discoverability and consistency with other sandbox providers. ([#14166](https://github.com/mastra-ai/mastra/pull/14166))

  ```typescript
  // Before
  const daytonaSandbox = sandbox.instance;

  // After
  const daytonaSandbox = sandbox.daytona;
  ```

#### Patch Changes

- Improved Daytona process handling to use provider session IDs directly as `ProcessHandle.pid`. ([#13591](https://github.com/mastra-ai/mastra/pull/13591))

  ```typescript
  const handle = await sandbox.processes.spawn('node server.js');
  await sandbox.processes.get(handle.pid);
  ```

- Fixed sandbox reconnection when Daytona sandbox is externally stopped or times out due to inactivity. Previously, the error thrown by the Daytona SDK (e.g. "failed to resolve container IP") did not match the known dead-sandbox patterns, so the automatic retry logic would not trigger and the error would propagate to the user. Added two new error patterns to correctly detect stopped sandboxes and trigger automatic recovery. ([#14175](https://github.com/mastra-ai/mastra/pull/14175))

### [@mastra/deployer@1.12.0](https://github.com/mastra-ai/mastra/blob/@mastra/deployer@1.12.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/deployer/CHANGELOG.md)
#### Patch Changes

- Improved Studio load times by serving compressed static assets in both deploy and dev. Large bundles now download much faster and use significantly less bandwidth. ([#13945](https://github.com/mastra-ai/mastra/pull/13945))

- --- ([#14162](https://github.com/mastra-ai/mastra/pull/14162))
  `@mastra/deployer`: patch

  ***

  Fixed deployment dependency resolution so required schema compatibility packages are resolved automatically.

- Fixed gzip compression being applied globally to all API routes, causing JSON responses to be unreadable by clients that don't auto-decompress. Compression is now scoped to studio static assets only. ([#14190](https://github.com/mastra-ai/mastra/pull/14190))

### [@mastra/e2b@0.1.2](https://github.com/mastra-ai/mastra/blob/@mastra/e2b@0.1.2//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/workspaces/e2b/CHANGELOG.md)
#### Patch Changes

- `ProcessHandle.pid` is now a string. Numeric PIDs from the E2B SDK are stringified automatically. ([#13591](https://github.com/mastra-ai/mastra/pull/13591))

  ```typescript
  const handle = await sandbox.processes.spawn('node server.js');
  handle.pid; // string (e.g., '1234')
  ```

### [@mastra/gcs@0.2.0](https://github.com/mastra-ai/mastra/blob/@mastra/gcs@0.2.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/workspaces/gcs/CHANGELOG.md)
#### Minor Changes

- Added public `storage` and `bucket` getters to access the underlying Google Cloud Storage instances directly. Use these when you need GCS features not exposed through the `WorkspaceFilesystem` interface. ([#14166](https://github.com/mastra-ai/mastra/pull/14166))

  ```typescript
  const gcsStorage = filesystem.storage;
  const gcsBucket = filesystem.bucket;
  ```

#### Patch Changes

### [@mastra/mcp@1.2.0](https://github.com/mastra-ai/mastra/blob/@mastra/mcp@1.2.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/mcp/CHANGELOG.md)
#### Minor Changes

- MCP client now attaches `mcpMetadata` (server name and version) to every tool it creates, enabling automatic `MCP_TOOL_CALL` span tracing without user code changes. ([#13274](https://github.com/mastra-ai/mastra/pull/13274))

#### Patch Changes

- Added `stderr` and `cwd` options to stdio server configuration so you can control child process error output and set the server working directory. ([#13959](https://github.com/mastra-ai/mastra/pull/13959))

  ```ts
  import { MCPClient } from '@mastra/mcp';

  const mcp = new MCPClient({
    servers: {
      myServer: {
        command: 'node',
        args: ['server.js'],
        stderr: 'pipe',
        cwd: '/path/to/server',
      },
    },
  });
  ```

### [@mastra/memory@1.7.0](https://github.com/mastra-ai/mastra/blob/@mastra/memory@1.7.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/memory/CHANGELOG.md)
#### Minor Changes

- Observational Memory now performs local threshold checks with lower CPU and memory overhead. ([#14178](https://github.com/mastra-ai/mastra/pull/14178))

  This update keeps the same multimodal thresholding behavior for image-aware inputs, so existing Observational Memory configurations continue to work without changes.

#### Patch Changes

### [@mastra/playground-ui@16.0.1](https://github.com/mastra-ai/mastra/blob/@mastra/playground-ui@16.0.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/playground-ui/CHANGELOG.md)
#### Patch Changes

- Updated form field components in Studio to use the new FieldBlock design system pattern. Replaced legacy SelectField, InputField, and SearchField with SelectFieldBlock, TextFieldBlock, and SearchFieldBlock across all domain components (observability, scores, datasets, templates). Refined button styles and layout improvements. ([#14138](https://github.com/mastra-ai/mastra/pull/14138))

- Fixed Studio form crash when workflow input schemas contain `z.array()` fields with Zod v4. Array, union, and intersection fields now render and accept input correctly in the workflow run form. ([#14131](https://github.com/mastra-ai/mastra/pull/14131))

- Added MCP-specific icon and color in trace timeline for `mcp_tool_call` spans. ([#13274](https://github.com/mastra-ai/mastra/pull/13274))

- Change file browser root path from `/` to `.` so workspace navigation starts from the workspace directory instead of the host filesystem root. ([#13804](https://github.com/mastra-ai/mastra/pull/13804))

### [@mastra/s3@0.3.0](https://github.com/mastra-ai/mastra/blob/@mastra/s3@0.3.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/workspaces/s3/CHANGELOG.md)
#### Minor Changes

- Added public `client` getter to access the underlying `S3Client` instance directly. Use this when you need S3 features not exposed through the `WorkspaceFilesystem` interface (e.g., presigned URLs, multipart uploads). ([#14166](https://github.com/mastra-ai/mastra/pull/14166))

  ```typescript
  const s3Client = filesystem.client;
  ```

#### Patch Changes

### [@mastra/schema-compat@1.2.1](https://github.com/mastra-ai/mastra/blob/@mastra/schema-compat@1.2.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/schema-compat/CHANGELOG.md)
#### Patch Changes

- Fixed Zod v4 schema conversion when `zod/v4` compat layer from Zod 3.25.x is used. Schemas like `ask_user` and other harness tools were not being properly converted to JSON Schema when `~standard.jsonSchema` was absent, causing `type: "None"` errors from the Anthropic API. ([#14157](https://github.com/mastra-ai/mastra/pull/14157))

### [@mastra/server@1.12.0](https://github.com/mastra-ai/mastra/blob/@mastra/server@1.12.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/server/CHANGELOG.md)
#### Patch Changes

- Fixed workspace filesystem permission errors returning HTTP 500 instead of 403. Permission denied errors now return the correct status code, preventing unnecessary client-side retries. ([#13804](https://github.com/mastra-ai/mastra/pull/13804))

### Other updated packages

The following packages were updated with dependency changes only:

- [@mastra/agent-builder@1.0.12](https://github.com/mastra-ai/mastra/blob/@mastra/agent-builder@1.0.12//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/agent-builder/CHANGELOG.md)
- [@mastra/client-js@1.8.1](https://github.com/mastra-ai/mastra/blob/@mastra/client-js@1.8.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/client-sdks/client-js/CHANGELOG.md)
- [@mastra/deployer-cloud@1.12.0](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-cloud@1.12.0//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/deployers/cloud/CHANGELOG.md)
- [@mastra/deployer-cloudflare@1.1.9](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-cloudflare@1.1.9//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/deployers/cloudflare/CHANGELOG.md)
- [@mastra/deployer-netlify@1.0.13](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-netlify@1.0.13//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/deployers/netlify/CHANGELOG.md)
- [@mastra/deployer-vercel@1.1.3](https://github.com/mastra-ai/mastra/blob/@mastra/deployer-vercel@1.1.3//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/deployers/vercel/CHANGELOG.md)
- [@mastra/express@1.2.1](https://github.com/mastra-ai/mastra/blob/@mastra/express@1.2.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/server-adapters/express/CHANGELOG.md)
- [@mastra/fastify@1.2.1](https://github.com/mastra-ai/mastra/blob/@mastra/fastify@1.2.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/server-adapters/fastify/CHANGELOG.md)
- [@mastra/hono@1.2.1](https://github.com/mastra-ai/mastra/blob/@mastra/hono@1.2.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/server-adapters/hono/CHANGELOG.md)
- [@mastra/koa@1.3.1](https://github.com/mastra-ai/mastra/blob/@mastra/koa@1.3.1//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/server-adapters/koa/CHANGELOG.md)
- [@mastra/longmemeval@1.0.13](https://github.com/mastra-ai/mastra/blob/@mastra/longmemeval@1.0.13//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/explorations/longmemeval/CHANGELOG.md)
- [@mastra/mcp-docs-server@1.1.10](https://github.com/mastra-ai/mastra/blob/@mastra/mcp-docs-server@1.1.10//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/packages/mcp-docs-server/CHANGELOG.md)
- [@mastra/opencode@0.0.10](https://github.com/mastra-ai/mastra/blob/@mastra/opencode@0.0.10//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/integrations/opencode/CHANGELOG.md)
- [@mastra/react@0.2.11](https://github.com/mastra-ai/mastra/blob/@mastra/react@0.2.11//private/var/folders/d4/mn8gvlx91cz80s_9c4gjr12r0000gn/T/mastra-mastra-ai-mastra-_mastra_core_1.12.0/client-sdks/react/CHANGELOG.md)