@mastra/mcp-docs-server 1.1.33-alpha.3 → 1.1.33-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/docs/agents/guardrails.md +60 -0
- package/.docs/docs/agents/processors.md +36 -0
- package/.docs/docs/deployment/workflow-runners.md +7 -1
- package/.docs/docs/mcp/overview.md +25 -0
- package/.docs/docs/server/auth/fga.md +141 -0
- package/.docs/docs/server/auth/workos.md +52 -9
- package/.docs/guides/deployment/temporal.md +232 -0
- package/.docs/models/gateways/openrouter.md +3 -1
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/alibaba.md +2 -1
- package/.docs/models/providers/cortecs.md +16 -2
- package/.docs/models/providers/firmware.md +7 -6
- package/.docs/models/providers/neuralwatt.md +84 -0
- package/.docs/models/providers/nvidia.md +2 -1
- package/.docs/models/providers/perplexity-agent.md +3 -1
- package/.docs/models/providers/synthetic.md +2 -1
- package/.docs/models/providers/zhipuai-coding-plan.md +9 -8
- package/.docs/models/providers.md +1 -0
- package/.docs/reference/auth/workos.md +54 -9
- package/.docs/reference/index.md +2 -0
- package/.docs/reference/processors/cost-guard-processor.md +112 -0
- package/.docs/reference/processors/processor-interface.md +5 -0
- package/.docs/reference/processors/regex-filter-processor.md +106 -0
- package/.docs/reference/tools/perplexity.md +0 -2
- package/.docs/reference/tools/tavily.md +0 -2
- package/CHANGELOG.md +8 -0
- package/package.json +5 -5
|
@@ -184,6 +184,28 @@ export const privateAgent = new Agent({
|
|
|
184
184
|
|
|
185
185
|
> **Note:** Visit [`PIIDetector()`](https://mastra.ai/reference/processors/pii-detector) reference for a full list of configuration options.
|
|
186
186
|
|
|
187
|
+
### Enforce cost limits
|
|
188
|
+
|
|
189
|
+
The `CostGuardProcessor()` monitors cumulative estimated cost across the agentic loop, blocking or warning when a monetary limit is exceeded. It queries cost data from observability storage before each LLM call. Cost checks are approximate — metrics are persisted asynchronously, so fast-running agents may briefly exceed the configured limit before the guard triggers.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { CostGuardProcessor } from '@mastra/core/processors'
|
|
193
|
+
|
|
194
|
+
export const budgetedAgent = new Agent({
|
|
195
|
+
id: 'budgeted-agent',
|
|
196
|
+
name: 'Budgeted Agent',
|
|
197
|
+
inputProcessors: [
|
|
198
|
+
new CostGuardProcessor({
|
|
199
|
+
maxCost: 5.0,
|
|
200
|
+
scope: 'thread',
|
|
201
|
+
window: '24h',
|
|
202
|
+
}),
|
|
203
|
+
],
|
|
204
|
+
})
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> **Note:** Visit [`CostGuardProcessor()`](https://mastra.ai/reference/processors/cost-guard-processor) reference for scoping modes, time windows, metric persistence delays, and the `onViolation` callback. Requires observability storage with `getMetricAggregate` support.
|
|
208
|
+
|
|
187
209
|
## Processor strategies
|
|
188
210
|
|
|
189
211
|
Many built-in processors support a `strategy` parameter that controls how they handle flagged content. Supported values include: `block`, `warn`, `detect`, `redact`, `rewrite`, and `translate`.
|
|
@@ -201,6 +223,44 @@ inputProcessors: [
|
|
|
201
223
|
]
|
|
202
224
|
```
|
|
203
225
|
|
|
226
|
+
## Violation callbacks
|
|
227
|
+
|
|
228
|
+
All processors support an `onViolation` callback that fires when a policy violation is detected, regardless of strategy. Use it for side effects like alerting, logging to external systems, or sending notifications.
|
|
229
|
+
|
|
230
|
+
The callback receives a `ProcessorViolation` object with `processorId`, `message`, and `detail` (processor-specific metadata).
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { CostGuardProcessor, ModerationProcessor, PIIDetector } from '@mastra/core/processors'
|
|
234
|
+
|
|
235
|
+
// Alert when cost limits are exceeded
|
|
236
|
+
const costGuard = new CostGuardProcessor({
|
|
237
|
+
maxCost: 10.0,
|
|
238
|
+
scope: 'resource',
|
|
239
|
+
window: '30d',
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
costGuard.onViolation = ({ processorId, message, detail }) => {
|
|
243
|
+
alertSystem.notify(`[${processorId}] ${message}`)
|
|
244
|
+
// detail contains: { usage, limit, totalUsage, scope, scopeKey }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Log moderation violations
|
|
248
|
+
const moderation = new ModerationProcessor({
|
|
249
|
+
model: 'openai/gpt-5-nano',
|
|
250
|
+
strategy: 'block',
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
moderation.onViolation = ({ processorId, message, detail }) => {
|
|
254
|
+
auditLog.write({ processor: processorId, violation: message, categories: detail })
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The `onViolation` property is part of the base [`Processor` interface](https://mastra.ai/reference/processors/processor-interface), so any processor — including custom ones — can use it. The runner automatically invokes `onViolation` when any processor calls `abort()`. For processors using a `warn` strategy (like `CostGuardProcessor`), the callback also fires on warnings without blocking the request.
|
|
259
|
+
|
|
260
|
+
Errors thrown by the callback are silently caught to prevent interfering with the processor's main logic.
|
|
261
|
+
|
|
262
|
+
For more on how violation callbacks integrate with the processor pipeline, see [Violation callbacks](https://mastra.ai/docs/agents/processors) in the Processors documentation.
|
|
263
|
+
|
|
204
264
|
## Handle blocked requests
|
|
205
265
|
|
|
206
266
|
When a processor calls `abort()`, the agent stops processing. How you detect this depends on whether you use `generate()` or `stream()`.
|
|
@@ -657,6 +657,42 @@ The retry mechanism:
|
|
|
657
657
|
- Tracks retry count via the `retryCount` parameter
|
|
658
658
|
- Respects `maxProcessorRetries` limit on the agent
|
|
659
659
|
|
|
660
|
+
### Violation callbacks
|
|
661
|
+
|
|
662
|
+
All processors expose an `onViolation` property that fires whenever a policy violation is detected — both when `abort()` is called (block strategy) and when a processor issues a warning (warn strategy). Use it for alerting, logging, or side effects without affecting the processor's main logic:
|
|
663
|
+
|
|
664
|
+
```typescript
|
|
665
|
+
import { ModerationProcessor, CostGuardProcessor } from '@mastra/core/processors'
|
|
666
|
+
|
|
667
|
+
const moderation = new ModerationProcessor({
|
|
668
|
+
model: 'openai/gpt-5-nano',
|
|
669
|
+
strategy: 'block',
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
moderation.onViolation = ({ processorId, message, detail }) => {
|
|
673
|
+
// Log to external monitoring, send alerts, update dashboards
|
|
674
|
+
monitor.track('processor_violation', { processorId, message, detail })
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const costGuard = new CostGuardProcessor({
|
|
678
|
+
maxCost: 10.0,
|
|
679
|
+
scope: 'resource',
|
|
680
|
+
window: '30d',
|
|
681
|
+
})
|
|
682
|
+
|
|
683
|
+
costGuard.onViolation = ({ processorId, message, detail }) => {
|
|
684
|
+
alertSystem.notify(`[${processorId}] ${message}`)
|
|
685
|
+
}
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
The callback receives a `ProcessorViolation` object with:
|
|
689
|
+
|
|
690
|
+
- `processorId`: The ID of the processor that detected the violation
|
|
691
|
+
- `message`: A human-readable description of what was violated
|
|
692
|
+
- `detail`: Processor-specific metadata (e.g. cost usage, detected PII types, moderation categories)
|
|
693
|
+
|
|
694
|
+
`onViolation` is part of the base [`Processor` interface](https://mastra.ai/reference/processors/processor-interface), so any custom processor can use it too. The runner automatically invokes it when any processor calls `abort()`. Errors thrown inside the callback are silently caught to prevent interfering with the processor pipeline.
|
|
695
|
+
|
|
660
696
|
### Abort and tripwire chunks
|
|
661
697
|
|
|
662
698
|
Calling `abort(reason, options)` throws a `TripWire` error that ends processing. On streams, Mastra emits a `tripwire` chunk clients can detect:
|
|
@@ -6,4 +6,10 @@ Mastra [workflows](https://mastra.ai/docs/workflows/overview) can be executed us
|
|
|
6
6
|
|
|
7
7
|
Inngest is a developer platform for running background workflows without managing infrastructure. Mastra workflows can be deployed to Inngest, which provides step memoization, automatic retries, real-time monitoring, and suspend/resume capabilities.
|
|
8
8
|
|
|
9
|
-
Visit the [Inngest deployment guide](https://mastra.ai/guides/deployment/inngest) for setup instructions and the [Inngest workflow example](https://github.com/mastra-ai/mastra/tree/main/examples/inngest) for a complete implementation.
|
|
9
|
+
Visit the [Inngest deployment guide](https://mastra.ai/guides/deployment/inngest) for setup instructions and the [Inngest workflow example](https://github.com/mastra-ai/mastra/tree/main/examples/inngest) for a complete implementation.
|
|
10
|
+
|
|
11
|
+
## Temporal
|
|
12
|
+
|
|
13
|
+
Temporal is a durable execution platform for orchestrating long-running workflows. Mastra workflows can run on Temporal workers, with each `createStep` mapped to a Temporal activity for automatic retries and durable state.
|
|
14
|
+
|
|
15
|
+
The `@mastra/temporal` package is experimental and not ready for production use. Visit the [Temporal deployment guide](https://mastra.ai/guides/deployment/temporal) for setup instructions.
|
|
@@ -332,6 +332,31 @@ const mcp = new MCPClient({
|
|
|
332
332
|
})
|
|
333
333
|
```
|
|
334
334
|
|
|
335
|
+
**Apify**:
|
|
336
|
+
|
|
337
|
+
[Apify](https://apify.com) is the largest marketplace of tools for AI, with thousands of ready-made [Actors](https://apify.com/store) to extract real-time data from any website, track competitors, generate leads, analyze sentiment, or orchestrate your apps. Connect your agent through the [Apify MCP Server](https://mcp.apify.com).
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { MCPClient } from '@mastra/mcp'
|
|
341
|
+
|
|
342
|
+
export const mcp = new MCPClient({
|
|
343
|
+
servers: {
|
|
344
|
+
apify: {
|
|
345
|
+
url: new URL('https://mcp.apify.com'),
|
|
346
|
+
requestInit: {
|
|
347
|
+
headers: {
|
|
348
|
+
Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
})
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Get your API token from the [Apify Console](https://console.apify.com/settings/integrations) and store it as `APIFY_TOKEN` in your environment.
|
|
357
|
+
|
|
358
|
+
To pick specific Actors and tools, use the [Apify MCP server configurator](https://mcp.apify.com) and copy the generated URL.
|
|
359
|
+
|
|
335
360
|
**Ampersand**:
|
|
336
361
|
|
|
337
362
|
[Ampersand](https://withampersand.com?utm_source=mastra-docs) offers an [MCP Server](https://docs.withampersand.com/mcp) that allows you to connect your agent to 150+ integrations with SaaS products like Salesforce, Hubspot, and Zendesk.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Fine-Grained Authorization (FGA)
|
|
2
|
+
|
|
3
|
+
Fine-Grained Authorization (FGA) adds resource-level permission checks to your Mastra application. While RBAC answers "can this role do this action?", FGA answers **"can this user do this action on this specific resource?"**
|
|
4
|
+
|
|
5
|
+
## When to use FGA
|
|
6
|
+
|
|
7
|
+
FGA is designed for multi-tenant B2B products where permissions are contextual:
|
|
8
|
+
|
|
9
|
+
- A user might be an **admin** of Team A but only a **member** of Team B
|
|
10
|
+
- Thread access should be limited to the user's own organization
|
|
11
|
+
- Workflow execution should be scoped to a specific team or project
|
|
12
|
+
- Tool access depends on the user's relationship to a resource
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
Configure FGA in your Mastra server config alongside authentication and RBAC:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
20
|
+
import { MastraFGAPermissions } from '@mastra/core/auth/ee';
|
|
21
|
+
import { MastraAuthWorkos, MastraFGAWorkos } from '@mastra/auth-workos';
|
|
22
|
+
|
|
23
|
+
const mastra = new Mastra({
|
|
24
|
+
server: {
|
|
25
|
+
auth: new MastraAuthWorkos({
|
|
26
|
+
/* ... */
|
|
27
|
+
fetchMemberships: true,
|
|
28
|
+
}),
|
|
29
|
+
fga: new MastraFGAWorkos({
|
|
30
|
+
resourceMapping: {
|
|
31
|
+
agent: { fgaResourceType: 'team', deriveId: (ctx) => ctx.user.teamId },
|
|
32
|
+
workflow: { fgaResourceType: 'team', deriveId: (ctx) => ctx.user.teamId },
|
|
33
|
+
thread: { fgaResourceType: 'workspace-thread', deriveId: ({ resourceId }) => resourceId },
|
|
34
|
+
},
|
|
35
|
+
permissionMapping: {
|
|
36
|
+
[MastraFGAPermissions.AGENTS_EXECUTE]: 'manage-workflows',
|
|
37
|
+
[MastraFGAPermissions.WORKFLOWS_EXECUTE]: 'manage-workflows',
|
|
38
|
+
[MastraFGAPermissions.MEMORY_READ]: 'read',
|
|
39
|
+
[MastraFGAPermissions.MEMORY_WRITE]: 'update',
|
|
40
|
+
},
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
When using `MastraFGAWorkos`, set `fetchMemberships: true` on `MastraAuthWorkos`. WorkOS FGA checks need the user's organization memberships to resolve the correct membership ID for authorization.
|
|
47
|
+
|
|
48
|
+
Use `thread` as the resource-mapping key for memory authorization. `MastraFGAWorkos` still accepts the legacy alias `memory`, but new configs should prefer `thread`.
|
|
49
|
+
|
|
50
|
+
### Resource mapping
|
|
51
|
+
|
|
52
|
+
The `resourceMapping` tells Mastra how to resolve FGA resource types and IDs from request context. Keys are Mastra resource types, values define the FGA resource type and how to derive the ID:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
resourceMapping: {
|
|
56
|
+
// When checking "can user execute agent X?", resolve the FGA resource
|
|
57
|
+
// as the user's team (type: 'team', id: user.teamId)
|
|
58
|
+
agent: {
|
|
59
|
+
fgaResourceType: 'team',
|
|
60
|
+
deriveId: (ctx) => ctx.user.teamId,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`deriveId()` receives:
|
|
66
|
+
|
|
67
|
+
- `user` — the authenticated user
|
|
68
|
+
- `resourceId` — the owning Mastra resource ID when available (for example, a thread's `resourceId`)
|
|
69
|
+
- `requestContext` — the current request context for advanced tenant resolution
|
|
70
|
+
|
|
71
|
+
Return `undefined` from `deriveId()` to fall back to the original Mastra resource ID.
|
|
72
|
+
|
|
73
|
+
For thread and memory checks, Mastra still passes the raw `threadId` as the resource being checked, but it also forwards the thread's owning `resourceId` into `deriveId()`. This lets you map thread permissions to composite tenant IDs such as `userId-teamId-orgId`.
|
|
74
|
+
|
|
75
|
+
### Permission mapping
|
|
76
|
+
|
|
77
|
+
The `permissionMapping` translates Mastra's internal permission strings to your FGA provider's permission slugs:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { MastraFGAPermissions } from '@mastra/core/auth/ee';
|
|
81
|
+
|
|
82
|
+
permissionMapping: {
|
|
83
|
+
[MastraFGAPermissions.AGENTS_EXECUTE]: 'manage-workflows', // Mastra permission -> WorkOS permission slug
|
|
84
|
+
[MastraFGAPermissions.MEMORY_READ]: 'read',
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If no mapping exists for a permission, the original string is passed through.
|
|
89
|
+
|
|
90
|
+
## Enforcement points
|
|
91
|
+
|
|
92
|
+
When an FGA provider is configured, Mastra automatically checks authorization at these lifecycle points:
|
|
93
|
+
|
|
94
|
+
| Lifecycle point | Permission checked | Resource |
|
|
95
|
+
| -------------------------------------- | ---------------------------------------------- | -------------------------------------- |
|
|
96
|
+
| Agent execution (`generate`, `stream`) | `agents:execute` | `{ type: 'agent', id: agentId }` |
|
|
97
|
+
| Workflow execution | `workflows:execute` | `{ type: 'workflow', id: workflowId }` |
|
|
98
|
+
| Tool execution | `tools:execute` | `{ type: 'tool', id: toolName }` |
|
|
99
|
+
| Thread/memory access | `memory:read`, `memory:write`, `memory:delete` | `{ type: 'thread', id: threadId }` |
|
|
100
|
+
| MCP tool execution | `tools:execute` | `{ type: 'tool', id: toolName }` |
|
|
101
|
+
| HTTP routes (opt-in) | Configured per route | Configured per route |
|
|
102
|
+
|
|
103
|
+
All checks are **no-ops when FGA is not configured**, maintaining backward compatibility.
|
|
104
|
+
|
|
105
|
+
## Custom FGA provider
|
|
106
|
+
|
|
107
|
+
Implement `IFGAProvider` to use any FGA backend:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { FGADeniedError } from '@mastra/core/auth/ee'
|
|
111
|
+
import type { FGACheckParams, IFGAProvider, MastraFGAPermissionInput } from '@mastra/core/auth/ee'
|
|
112
|
+
|
|
113
|
+
class MyFGAProvider implements IFGAProvider {
|
|
114
|
+
async check(user: any, params: FGACheckParams): Promise<boolean> {
|
|
115
|
+
// Your authorization logic
|
|
116
|
+
return true
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async require(user: any, params: FGACheckParams): Promise<void> {
|
|
120
|
+
const allowed = await this.check(user, params)
|
|
121
|
+
if (!allowed) {
|
|
122
|
+
throw new FGADeniedError(user, params.resource, params.permission)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async filterAccessible<T extends { id: string }>(
|
|
127
|
+
user: any,
|
|
128
|
+
resources: T[],
|
|
129
|
+
resourceType: string,
|
|
130
|
+
permission: MastraFGAPermissionInput,
|
|
131
|
+
): Promise<T[]> {
|
|
132
|
+
// Filter resources the user can access
|
|
133
|
+
return resources
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Related
|
|
139
|
+
|
|
140
|
+
- [Authentication overview](https://mastra.ai/docs/server/auth)
|
|
141
|
+
- [WorkOS authentication](https://mastra.ai/docs/server/auth/workos)
|
|
@@ -81,16 +81,34 @@ export const mastra = new Mastra({
|
|
|
81
81
|
|
|
82
82
|
## Configuration
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Default authorization
|
|
85
85
|
|
|
86
|
-
By default, `MastraAuthWorkos`
|
|
86
|
+
By default, `MastraAuthWorkos` grants access to any authenticated WorkOS user. The authorization check succeeds when the resolved user object contains both a Mastra user ID and a WorkOS user ID.
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
2. Extracts all roles from their memberships
|
|
90
|
-
3. Checks if any role has the slug 'admin'
|
|
91
|
-
4. Grants access only if the user has admin role in at least one organization
|
|
88
|
+
### FGA membership loading
|
|
92
89
|
|
|
93
|
-
|
|
90
|
+
Set `fetchMemberships: true` when you use [`MastraFGAWorkos`](https://mastra.ai/docs/server/auth/fga). This tells the auth provider to load the user's WorkOS organization memberships during authentication so FGA checks can resolve the correct organization membership ID.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { MastraAuthWorkos, MastraFGAWorkos } from '@mastra/auth-workos'
|
|
94
|
+
|
|
95
|
+
const workosAuth = new MastraAuthWorkos({
|
|
96
|
+
apiKey: process.env.WORKOS_API_KEY,
|
|
97
|
+
clientId: process.env.WORKOS_CLIENT_ID,
|
|
98
|
+
fetchMemberships: true,
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
const workosFga = new MastraFGAWorkos({
|
|
102
|
+
apiKey: process.env.WORKOS_API_KEY,
|
|
103
|
+
clientId: process.env.WORKOS_CLIENT_ID,
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
When `fetchMemberships` is `false`, Mastra skips the extra WorkOS `listOrganizationMemberships()` call on each authenticated request.
|
|
108
|
+
|
|
109
|
+
### Service tokens and custom JWT templates
|
|
110
|
+
|
|
111
|
+
For machine-to-machine or service-account access, you can configure `MastraAuthWorkos` to trust verified bearer-token claims from a WorkOS custom JWT template.
|
|
94
112
|
|
|
95
113
|
```typescript
|
|
96
114
|
import { MastraAuthWorkos } from '@mastra/auth-workos'
|
|
@@ -98,12 +116,37 @@ import { MastraAuthWorkos } from '@mastra/auth-workos'
|
|
|
98
116
|
const workosAuth = new MastraAuthWorkos({
|
|
99
117
|
apiKey: process.env.WORKOS_API_KEY,
|
|
100
118
|
clientId: process.env.WORKOS_CLIENT_ID,
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
redirectUri: process.env.WORKOS_REDIRECT_URI,
|
|
120
|
+
trustJwtClaims: true,
|
|
121
|
+
jwtClaims: {
|
|
122
|
+
organizationId: 'org_id',
|
|
123
|
+
organizationMembershipId: 'urn:mastra:organization_membership_id',
|
|
103
124
|
},
|
|
104
125
|
})
|
|
105
126
|
```
|
|
106
127
|
|
|
128
|
+
This is useful when your JWT template already includes the exact FGA context Mastra needs, such as `organizationMembershipId`, tenant IDs, or service-principal identifiers. When `trustJwtClaims` is enabled, Mastra can fall back to those verified claims if a bearer token is not meant to round-trip through `workos.userManagement.getUser()`.
|
|
129
|
+
|
|
130
|
+
### Custom authorization
|
|
131
|
+
|
|
132
|
+
If you need stricter authorization, subclass `MastraAuthWorkos` and override `authorizeUser()`:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { MastraAuthWorkos } from '@mastra/auth-workos'
|
|
136
|
+
import type { HonoRequest } from 'hono'
|
|
137
|
+
|
|
138
|
+
class AdminOnlyWorkosAuth extends MastraAuthWorkos {
|
|
139
|
+
async authorizeUser(user: any, _request: HonoRequest): Promise<boolean> {
|
|
140
|
+
return user?.metadata?.role === 'admin'
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const workosAuth = new AdminOnlyWorkosAuth({
|
|
145
|
+
apiKey: process.env.WORKOS_API_KEY,
|
|
146
|
+
clientId: process.env.WORKOS_CLIENT_ID,
|
|
147
|
+
})
|
|
148
|
+
```
|
|
149
|
+
|
|
107
150
|
> **Info:** Visit [MastraAuthWorkos](https://mastra.ai/reference/auth/workos) for all available configuration options.
|
|
108
151
|
|
|
109
152
|
## Client-side setup
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Temporal workflow
|
|
2
|
+
|
|
3
|
+
[Temporal](https://temporal.io/) is a durable execution platform for orchestrating long-running, fault-tolerant workflows. The `@mastra/temporal` package lets you author workflows with the standard Mastra API and run them on a Temporal cluster.
|
|
4
|
+
|
|
5
|
+
> **Warning:** `@mastra/temporal` is experimental and not ready for production use. The API may change between releases. See the [package README](https://github.com/mastra-ai/mastra/tree/main/workflows/temporal) for the current state.
|
|
6
|
+
|
|
7
|
+
## How Temporal works with Mastra
|
|
8
|
+
|
|
9
|
+
Mastra workflows authored with `createWorkflow()` and `createStep()` map onto Temporal's workflow and activity model. The `MastraPlugin` for the Temporal worker compiles your Mastra entry file at bundle time:
|
|
10
|
+
|
|
11
|
+
- Each `createStep()` handler is extracted into a Temporal activity.
|
|
12
|
+
- Each `createWorkflow()` is rewritten into a Temporal workflow that invokes those activities.
|
|
13
|
+
- The plugin registers the generated activities and workflows with the worker automatically.
|
|
14
|
+
|
|
15
|
+
When a run starts through `mastra.getWorkflow(...).createRun().start(...)`, the Mastra client hands control to Temporal. Temporal then drives durable execution, retries, and state persistence on the worker.
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
Install the required packages:
|
|
20
|
+
|
|
21
|
+
**npm**:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @mastra/temporal@latest @temporalio/client @temporalio/worker @temporalio/envconfig
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**pnpm**:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @mastra/temporal@latest @temporalio/client @temporalio/worker @temporalio/envconfig
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Yarn**:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yarn add @mastra/temporal@latest @temporalio/client @temporalio/worker @temporalio/envconfig
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Bun**:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun add @mastra/temporal@latest @temporalio/client @temporalio/worker @temporalio/envconfig
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
You also need access to a Temporal cluster. For local development, you can run one with Docker (see [Running locally](#running-locally)).
|
|
46
|
+
|
|
47
|
+
## Building a Temporal-backed workflow
|
|
48
|
+
|
|
49
|
+
This guide walks through creating a workflow with Temporal and Mastra, demonstrating a counter application that increments a value.
|
|
50
|
+
|
|
51
|
+
### Temporal initialization
|
|
52
|
+
|
|
53
|
+
Initialize the Temporal integration to obtain Mastra-compatible workflow helpers. The `createWorkflow()` and `createStep()` functions are bound to a Temporal client and a task queue.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { init } from '@mastra/temporal'
|
|
57
|
+
import { Client, Connection } from '@temporalio/client'
|
|
58
|
+
import { loadClientConnectConfig } from '@temporalio/envconfig'
|
|
59
|
+
|
|
60
|
+
const config = loadClientConnectConfig()
|
|
61
|
+
const connection = await Connection.connect(config.connectionOptions)
|
|
62
|
+
const client = new Client({ connection })
|
|
63
|
+
|
|
64
|
+
export const { createWorkflow, createStep } = init({
|
|
65
|
+
client,
|
|
66
|
+
taskQueue: 'mastra',
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`loadClientConnectConfig()` reads standard Temporal environment variables such as `TEMPORAL_ADDRESS`, `TEMPORAL_NAMESPACE`, and mTLS settings. See the [Temporal envconfig docs](https://docs.temporal.io/develop/typescript/temporal-clients) for the full list.
|
|
71
|
+
|
|
72
|
+
### Creating steps
|
|
73
|
+
|
|
74
|
+
Define the individual steps that will compose your workflow. Each step becomes a Temporal activity.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { z } from 'zod'
|
|
78
|
+
import { createWorkflow, createStep } from '../temporal'
|
|
79
|
+
|
|
80
|
+
const incrementStep = createStep({
|
|
81
|
+
id: 'increment',
|
|
82
|
+
inputSchema: z.object({
|
|
83
|
+
value: z.number(),
|
|
84
|
+
}),
|
|
85
|
+
outputSchema: z.object({
|
|
86
|
+
value: z.number(),
|
|
87
|
+
}),
|
|
88
|
+
execute: async ({ inputData }) => {
|
|
89
|
+
return { value: inputData.value + 1 }
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Creating the workflow
|
|
95
|
+
|
|
96
|
+
Compose the steps into a workflow. The workflow `id` must be a static string literal so the build-time transformer can derive its Temporal export name.
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
const workflow = createWorkflow({
|
|
100
|
+
id: 'increment-workflow',
|
|
101
|
+
steps: [incrementStep],
|
|
102
|
+
inputSchema: z.object({
|
|
103
|
+
value: z.number(),
|
|
104
|
+
}),
|
|
105
|
+
outputSchema: z.object({
|
|
106
|
+
value: z.number(),
|
|
107
|
+
}),
|
|
108
|
+
}).then(incrementStep)
|
|
109
|
+
|
|
110
|
+
workflow.commit()
|
|
111
|
+
|
|
112
|
+
export { workflow as incrementWorkflow }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Configuring the Mastra instance
|
|
116
|
+
|
|
117
|
+
Register the workflow with Mastra. The execution is driven by the Temporal worker.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
import { Mastra } from '@mastra/core'
|
|
121
|
+
import { PinoLogger } from '@mastra/loggers'
|
|
122
|
+
import { incrementWorkflow } from './workflows'
|
|
123
|
+
|
|
124
|
+
export const mastra = new Mastra({
|
|
125
|
+
workflows: { incrementWorkflow },
|
|
126
|
+
logger: new PinoLogger({ name: 'Mastra', level: 'info' }),
|
|
127
|
+
})
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Running the worker
|
|
131
|
+
|
|
132
|
+
The worker is a long-lived Node.js process that polls a Temporal task queue. Install `MastraPlugin` and point its `src` option at the Mastra entry file that registers your workflows.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { MastraPlugin } from '@mastra/temporal/worker'
|
|
136
|
+
import { NativeConnection, Worker } from '@temporalio/worker'
|
|
137
|
+
|
|
138
|
+
const connection = await NativeConnection.connect({
|
|
139
|
+
address: 'localhost:7233',
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const mastraPlugin = new MastraPlugin()
|
|
143
|
+
|
|
144
|
+
await mastraPlugin.prebuild({
|
|
145
|
+
entryFile: import.meta.resolve('./index.ts'),
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
const worker = await Worker.create({
|
|
149
|
+
connection,
|
|
150
|
+
namespace: 'default',
|
|
151
|
+
taskQueue: 'mastra',
|
|
152
|
+
plugins: [mastraPlugin],
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
await worker.run()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`MastraPlugin` rewrites the entry file into a workflow-only bundle and wires step handlers in as Temporal activities. You do not need to pass `activities` or `workflowsPath` to `Worker.create()` manually.
|
|
159
|
+
|
|
160
|
+
## Running workflows
|
|
161
|
+
|
|
162
|
+
### Running locally
|
|
163
|
+
|
|
164
|
+
1. Start a local Temporal server. The simplest option is the `temporalio/auto-setup` Docker image:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
docker run --rm -p 7233:7233 -p 8080:8080 temporalio/auto-setup:latest
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
2. Open the Temporal UI at <http://localhost:8080> to inspect namespaces, workflows, and activities.
|
|
171
|
+
|
|
172
|
+
3. Start the worker. In a new terminal, run:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx tsx src/mastra/worker.ts
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
4. Trigger a workflow run from a script or any process that imports your Mastra instance:
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { mastra } from '../src/mastra'
|
|
182
|
+
|
|
183
|
+
const run = await mastra.getWorkflow('incrementWorkflow').createRun()
|
|
184
|
+
const result = await run.start({ inputData: { value: 5 } })
|
|
185
|
+
|
|
186
|
+
console.log(result)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
5. Monitor execution in the Temporal UI under **Workflows** to see step-by-step activity progress and retry history.
|
|
190
|
+
|
|
191
|
+
### Running in production
|
|
192
|
+
|
|
193
|
+
For production, use [Temporal Cloud](https://temporal.io/cloud) or a self-hosted Temporal cluster. Configure the client and worker connections through environment variables read by `@temporalio/envconfig`:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
TEMPORAL_ADDRESS=your-namespace.tmprl.cloud:7233
|
|
197
|
+
TEMPORAL_NAMESPACE=your-namespace
|
|
198
|
+
TEMPORAL_API_KEY=your-api-key
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
See the [Temporal Cloud connection docs](https://docs.temporal.io/cloud/get-started) for mTLS and API key options.
|
|
202
|
+
|
|
203
|
+
> **Warning:** The Temporal worker must run as a long-lived process. Do not deploy it to serverless platforms with short execution limits, such as AWS Lambda or Vercel functions. Use a container, VM, or worker-friendly platform such as Fly.io, Railway, or Kubernetes.
|
|
204
|
+
|
|
205
|
+
## Configuration options
|
|
206
|
+
|
|
207
|
+
### `taskQueue`
|
|
208
|
+
|
|
209
|
+
Required. Identifies the Temporal task queue your worker polls. The same value must be passed to `init()` (used by the client to start runs) and to `Worker.create()` (used by the worker to receive them).
|
|
210
|
+
|
|
211
|
+
### `startToCloseTimeout`
|
|
212
|
+
|
|
213
|
+
Optional. Sets the maximum time a single activity (step) is allowed to run before Temporal cancels it and applies the retry policy. Defaults to `1 minute`.
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
export const { createWorkflow, createStep } = init({
|
|
217
|
+
client,
|
|
218
|
+
taskQueue: 'mastra',
|
|
219
|
+
startToCloseTimeout: '5 minutes',
|
|
220
|
+
})
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Constraints and notes
|
|
224
|
+
|
|
225
|
+
- Workflow ids must be static string literals. The build-time transformer reads the literal value to derive Temporal workflow export names.
|
|
226
|
+
- Activities are generated automatically from `createStep()` handlers. Do not pass them in `Worker.create({ activities })`.
|
|
227
|
+
|
|
228
|
+
## Related
|
|
229
|
+
|
|
230
|
+
- [Workflow runners](https://mastra.ai/docs/deployment/workflow-runners)
|
|
231
|
+
- [Workflows overview](https://mastra.ai/docs/workflows/overview)
|
|
232
|
+
- [Temporal documentation](https://docs.temporal.io/)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OpenRouter
|
|
2
2
|
|
|
3
|
-
OpenRouter aggregates models from multiple providers with enhanced features like rate limiting and failover. Access
|
|
3
|
+
OpenRouter aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 184 models through Mastra's model router.
|
|
4
4
|
|
|
5
5
|
Learn more in the [OpenRouter documentation](https://openrouter.ai/models).
|
|
6
6
|
|
|
@@ -168,6 +168,8 @@ ANTHROPIC_API_KEY=ant-...
|
|
|
168
168
|
| `openrouter/free` |
|
|
169
169
|
| `openrouter/owl-alpha` |
|
|
170
170
|
| `openrouter/pareto-code` |
|
|
171
|
+
| `poolside/laguna-m.1:free` |
|
|
172
|
+
| `poolside/laguna-xs.2:free` |
|
|
171
173
|
| `prime-intellect/intellect-3` |
|
|
172
174
|
| `qwen/qwen-2.5-coder-32b-instruct` |
|
|
173
175
|
| `qwen/qwen2.5-vl-72b-instruct` |
|
package/.docs/models/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Model Providers
|
|
2
2
|
|
|
3
|
-
Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to
|
|
3
|
+
Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 3869 models from 107 providers through a single API.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Alibaba
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 48 Alibaba models through Mastra's model router. Authentication is handled automatically using the `DASHSCOPE_API_KEY` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [Alibaba documentation](https://www.alibabacloud.com/help/en/model-studio/models).
|
|
6
6
|
|
|
@@ -79,6 +79,7 @@ for await (const chunk of stream) {
|
|
|
79
79
|
| `alibaba/qwen3.5-plus` | 1.0M | | | | | | $0.40 | $2 |
|
|
80
80
|
| `alibaba/qwen3.6-27b` | 262K | | | | | | $0.60 | $4 |
|
|
81
81
|
| `alibaba/qwen3.6-35b-a3b` | 262K | | | | | | $0.25 | $1 |
|
|
82
|
+
| `alibaba/qwen3.6-max-preview` | 262K | | | | | | $1 | $8 |
|
|
82
83
|
| `alibaba/qwen3.6-plus` | 1.0M | | | | | | $0.28 | $2 |
|
|
83
84
|
| `alibaba/qwq-plus` | 131K | | | | | | $0.80 | $2 |
|
|
84
85
|
|