@mastra/mcp-docs-server 1.2.2-alpha.9 → 1.2.3-alpha.1
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/{harness → agent-controller}/modes.md +19 -19
- package/.docs/docs/agent-controller/overview.md +128 -0
- package/.docs/docs/agent-controller/session.md +143 -0
- package/.docs/docs/{harness → agent-controller}/subagents.md +12 -12
- package/.docs/docs/agent-controller/threads-and-state.md +141 -0
- package/.docs/docs/{harness → agent-controller}/tool-approvals.md +23 -23
- package/.docs/docs/agents/channels.md +47 -0
- package/.docs/docs/server/auth/google.md +281 -0
- package/.docs/docs/server/auth.md +2 -1
- package/.docs/models/gateways/vercel.md +3 -1
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/baseten.md +1 -1
- package/.docs/models/providers/fireworks-ai.md +2 -1
- package/.docs/models/providers/friendli.md +3 -1
- package/.docs/models/providers/llmgateway.md +1 -2
- package/.docs/models/providers/nebius.md +3 -2
- package/.docs/models/providers/opencode-go.md +1 -1
- package/.docs/models/providers/ovhcloud.md +1 -2
- package/.docs/models/providers/scaleway.md +2 -1
- package/.docs/models/providers/tinfoil.md +77 -0
- package/.docs/models/providers/togetherai.md +3 -2
- package/.docs/models/providers/xiaomi-token-plan-ams.md +4 -6
- package/.docs/models/providers/xiaomi-token-plan-cn.md +4 -6
- package/.docs/models/providers/xiaomi-token-plan-sgp.md +4 -6
- package/.docs/models/providers/xiaomi.md +4 -7
- package/.docs/models/providers.md +1 -0
- package/.docs/reference/{harness/harness-class.md → agent-controller/agent-controller-class.md} +106 -106
- package/.docs/reference/{harness → agent-controller}/session.md +97 -91
- package/.docs/reference/agents/channels.md +3 -1
- package/.docs/reference/agents/durable-agent.md +30 -3
- package/.docs/reference/auth/google.md +355 -0
- package/.docs/reference/channels/channel-provider.md +65 -0
- package/.docs/reference/channels/slack-provider.md +226 -0
- package/.docs/reference/index.md +5 -2
- package/CHANGELOG.md +28 -0
- package/package.json +6 -6
- package/.docs/docs/harness/overview.md +0 -128
- package/.docs/docs/harness/session.md +0 -143
- package/.docs/docs/harness/threads-and-state.md +0 -141
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tool approvals and permissions
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The AgentController provides a permission system that controls which tools require user approval before execution. You can configure policies at the category level or per-tool, and grant session-wide exceptions for trusted tools. This gives agents with access to destructive or sensitive tools — file writes, command execution, API calls — a human-in-the-loop checkpoint before those tools run.
|
|
4
4
|
|
|
5
5
|
## Permission policies
|
|
6
6
|
|
|
@@ -16,18 +16,18 @@ Set policies per-category or per-tool. Per-tool policies take precedence over ca
|
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
18
|
// Category-level: all execute tools require approval
|
|
19
|
-
await
|
|
19
|
+
await agentController.session.permissions.setForCategory({ category: 'execute', policy: 'ask' })
|
|
20
20
|
|
|
21
21
|
// Tool-level: this specific tool is always blocked
|
|
22
|
-
await
|
|
22
|
+
await agentController.session.permissions.setForTool({ toolName: 'dangerous_tool', policy: 'deny' })
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Tool categories
|
|
26
26
|
|
|
27
|
-
The `toolCategoryResolver` maps tool names to categories. Pass it to the
|
|
27
|
+
The `toolCategoryResolver` maps tool names to categories. Pass it to the AgentController constructor:
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
|
-
const
|
|
30
|
+
const agentController = new AgentController({
|
|
31
31
|
id: 'my-agent',
|
|
32
32
|
toolCategoryResolver: toolName => {
|
|
33
33
|
if (toolName.includes('write') || toolName.includes('delete')) return 'edit'
|
|
@@ -41,13 +41,13 @@ Built-in categories are `read`, `edit`, `execute`, `mcp`, and `other`.
|
|
|
41
41
|
|
|
42
42
|
## Responding to approval requests
|
|
43
43
|
|
|
44
|
-
When a tool's policy is `ask`, the
|
|
44
|
+
When a tool's policy is `ask`, the AgentController emits a `tool_approval_required` event. Your UI should display a prompt and call `session.respondToToolApproval()`:
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
-
|
|
47
|
+
agentController.subscribe(event => {
|
|
48
48
|
if (event.type === 'tool_approval_required') {
|
|
49
49
|
// Show approval UI...
|
|
50
|
-
|
|
50
|
+
agentController.session.respondToToolApproval({ decision: 'approve' })
|
|
51
51
|
}
|
|
52
52
|
})
|
|
53
53
|
```
|
|
@@ -55,22 +55,22 @@ harness.subscribe(event => {
|
|
|
55
55
|
The `decision` field accepts `'approve'`, `'decline'`, or `'always_allow_category'`. When `always_allow_category` is used, the tool's category is granted for the rest of the session. Future tools in the same category are auto-approved.
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
|
-
|
|
58
|
+
agentController.session.respondToToolApproval({ decision: 'always_allow_category' })
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
## Session grants
|
|
62
62
|
|
|
63
|
-
The
|
|
63
|
+
The AgentController owns permission _policy_ (which categories require approval); the [`Session`](https://mastra.ai/docs/agent-controller/session) owns the _grants_ a user makes during a conversation. Grant a category or tool for the rest of the session so it runs without further prompting:
|
|
64
64
|
|
|
65
65
|
```typescript
|
|
66
66
|
// Grant all edit tools for this session
|
|
67
|
-
|
|
67
|
+
agentController.session.grantCategory('edit')
|
|
68
68
|
|
|
69
69
|
// Grant a specific tool
|
|
70
|
-
|
|
70
|
+
agentController.session.grantTool('mastra_workspace_execute_command')
|
|
71
71
|
|
|
72
72
|
// Check current grants
|
|
73
|
-
const grants =
|
|
73
|
+
const grants = agentController.session.getGrants()
|
|
74
74
|
// { categories: ['edit'], tools: ['mastra_workspace_execute_command'] }
|
|
75
75
|
```
|
|
76
76
|
|
|
@@ -79,11 +79,11 @@ const grants = harness.session.getGrants()
|
|
|
79
79
|
Interactive built-in tools (`ask_user`, `submit_plan`) use the native tool-suspension primitive instead of the approval flow. They emit a `tool_suspended` event with `toolCallId`, `toolName`, and `suspendPayload`. Resume with `respondToToolSuspension()`:
|
|
80
80
|
|
|
81
81
|
```typescript
|
|
82
|
-
|
|
82
|
+
agentController.subscribe(event => {
|
|
83
83
|
if (event.type === 'tool_suspended' && event.toolName === 'ask_user') {
|
|
84
84
|
const { question } = event.suspendPayload as { question: string }
|
|
85
85
|
// Show question to user, then resume:
|
|
86
|
-
|
|
86
|
+
agentController.respondToToolSuspension({
|
|
87
87
|
toolCallId: event.toolCallId,
|
|
88
88
|
resumeData: 'User response here',
|
|
89
89
|
})
|
|
@@ -97,13 +97,13 @@ The `submit_plan` tool suspends via the same mechanism. Resume with an `action`
|
|
|
97
97
|
|
|
98
98
|
```typescript
|
|
99
99
|
// Approve the plan
|
|
100
|
-
|
|
100
|
+
agentController.respondToToolSuspension({
|
|
101
101
|
toolCallId: event.toolCallId,
|
|
102
102
|
resumeData: { action: 'approved' },
|
|
103
103
|
})
|
|
104
104
|
|
|
105
105
|
// Reject with feedback
|
|
106
|
-
|
|
106
|
+
agentController.respondToToolSuspension({
|
|
107
107
|
toolCallId: event.toolCallId,
|
|
108
108
|
resumeData: { action: 'rejected', feedback: 'Needs more detail' },
|
|
109
109
|
})
|
|
@@ -111,7 +111,7 @@ harness.respondToToolSuspension({
|
|
|
111
111
|
|
|
112
112
|
## Built-in tools
|
|
113
113
|
|
|
114
|
-
The
|
|
114
|
+
The AgentController provides these built-in tools to agents in every mode:
|
|
115
115
|
|
|
116
116
|
| Tool | Description |
|
|
117
117
|
| --------------- | ------------------------------------------------------------------- |
|
|
@@ -126,7 +126,7 @@ The Harness provides these built-in tools to agents in every mode:
|
|
|
126
126
|
Disable specific built-in tools with `disableBuiltinTools`:
|
|
127
127
|
|
|
128
128
|
```typescript
|
|
129
|
-
const
|
|
129
|
+
const agentController = new AgentController({
|
|
130
130
|
id: 'no-plans',
|
|
131
131
|
disableBuiltinTools: ['submit_plan'],
|
|
132
132
|
})
|
|
@@ -134,8 +134,8 @@ const harness = new Harness({
|
|
|
134
134
|
|
|
135
135
|
## Related
|
|
136
136
|
|
|
137
|
-
- [
|
|
138
|
-
- [Session](https://mastra.ai/docs/
|
|
139
|
-
- [Subagents](https://mastra.ai/docs/
|
|
137
|
+
- [AgentController overview](https://mastra.ai/docs/agent-controller/overview)
|
|
138
|
+
- [Session](https://mastra.ai/docs/agent-controller/session)
|
|
139
|
+
- [Subagents](https://mastra.ai/docs/agent-controller/subagents)
|
|
140
140
|
- [Agent approval](https://mastra.ai/docs/agents/agent-approval)
|
|
141
|
-
- [API reference](https://mastra.ai/reference/
|
|
141
|
+
- [API reference](https://mastra.ai/reference/agent-controller/agent-controller-class)
|
|
@@ -164,6 +164,53 @@ By default, only images are sent inline (`inlineMedia: ['image/*']`). Unsupporte
|
|
|
164
164
|
|
|
165
165
|
> **Note:** See [Channels reference](https://mastra.ai/reference/agents/channels) for all `inlineMedia` patterns and [inlineLinks reference](https://mastra.ai/reference/agents/channels) for domain matching, HEAD detection, and forced mime types.
|
|
166
166
|
|
|
167
|
+
## Serverless deployment
|
|
168
|
+
|
|
169
|
+
On serverless platforms like Vercel, each request runs in a separate, short-lived instance. Channels need two things to work reliably in that environment: a way to keep the function alive while the agent responds, and a shared pub/sub so instances can coordinate.
|
|
170
|
+
|
|
171
|
+
### Keep the function alive with `waitUntil`
|
|
172
|
+
|
|
173
|
+
A channel webhook returns a `200` response right away, then the agent runs in the background to post its reply. On most serverless platforms the function is frozen as soon as it responds, which kills the run before the agent answers. Pass a `waitUntil` function so the platform keeps the instance alive until the run finishes.
|
|
174
|
+
|
|
175
|
+
On Vercel, pass `waitUntil` from `@vercel/functions`:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { waitUntil } from '@vercel/functions'
|
|
179
|
+
|
|
180
|
+
export const agent = new Agent({
|
|
181
|
+
// ...
|
|
182
|
+
channels: {
|
|
183
|
+
adapters: {
|
|
184
|
+
slack: createSlackAdapter(),
|
|
185
|
+
},
|
|
186
|
+
waitUntil,
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Vercel and AWS Lambda require `waitUntil`, since they freeze the function as soon as the response is sent. Cloudflare Workers and Netlify Functions are detected automatically from the request context, so they don't need it. For runtimes where `waitUntil` lives on the request context but isn't detected automatically, use `resolveWaitUntil`. See the [Channels reference](https://mastra.ai/reference/agents/channels) for details.
|
|
192
|
+
|
|
193
|
+
### Coordinate instances with a shared pub/sub
|
|
194
|
+
|
|
195
|
+
Channels route messages through the agent's signal pipeline, and each run acquires a lease on its thread so a single run owns the conversation at a time. The default in-memory pub/sub can't cross instance boundaries, so on serverless a follow-up message can land on a different instance than the one running the agent. Without a shared pub/sub, that instance can't reach the active run and starts its own, leaving the original run untouched and the thread processed twice.
|
|
196
|
+
|
|
197
|
+
Configure a shared pub/sub backed by Redis Streams on the `Mastra` instance so leases and signals coordinate across instances:
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { Mastra } from '@mastra/core'
|
|
201
|
+
import { RedisStreamsPubSub } from '@mastra/redis-streams'
|
|
202
|
+
|
|
203
|
+
export const mastra = new Mastra({
|
|
204
|
+
agents: { agent },
|
|
205
|
+
pubsub: new RedisStreamsPubSub({
|
|
206
|
+
url: process.env.REDIS_URL,
|
|
207
|
+
keyPrefix: 'mastra:my-app',
|
|
208
|
+
}),
|
|
209
|
+
})
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Vercel's one-click Redis integration and Upstash Redis both work well. For more on when a distributed pub/sub is needed, see the [PubSub guide](https://mastra.ai/docs/server/pubsub) and the [`RedisStreamsPubSub` reference](https://mastra.ai/reference/pubsub/redis-streams).
|
|
213
|
+
|
|
167
214
|
## Related
|
|
168
215
|
|
|
169
216
|
- [Guide: Building a Slack assistant](https://mastra.ai/guides/guide/slack-assistant)
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Google
|
|
2
|
+
|
|
3
|
+
The `@mastra/auth-google` package provides authentication and role-based access control for Mastra using Google Workspace. It supports an OAuth 2.0 / OIDC login flow with encrypted session cookies, verifies Google ID tokens, and maps Google Workspace groups to Mastra permissions.
|
|
4
|
+
|
|
5
|
+
Use it when your Studio users sign in with Google and access should be limited to one or more Google Workspace domains.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
This guide uses Google Workspace authentication. Make sure to:
|
|
10
|
+
|
|
11
|
+
1. Create or select a Google Cloud project
|
|
12
|
+
2. Set up an OAuth client for web applications
|
|
13
|
+
3. Add your Mastra SSO callback URL to the authorized redirect URIs
|
|
14
|
+
4. Configure Google Workspace groups if you plan to use RBAC
|
|
15
|
+
|
|
16
|
+
For Google Groups RBAC, also configure a Google Workspace service account with domain-wide delegation and grant it the Directory API read-only group scope:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
https://www.googleapis.com/auth/admin.directory.group.readonly
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Make sure your environment variables are set.
|
|
23
|
+
|
|
24
|
+
```env
|
|
25
|
+
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
|
26
|
+
GOOGLE_CLIENT_SECRET=your-client-secret
|
|
27
|
+
GOOGLE_REDIRECT_URI=http://localhost:4111/api/auth/sso/callback
|
|
28
|
+
GOOGLE_COOKIE_PASSWORD=a-random-string-at-least-32-characters-long
|
|
29
|
+
GOOGLE_ALLOWED_DOMAINS=example.com
|
|
30
|
+
|
|
31
|
+
GOOGLE_SERVICE_ACCOUNT_EMAIL=service-account@project.iam.gserviceaccount.com
|
|
32
|
+
GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
|
|
33
|
+
GOOGLE_WORKSPACE_ADMIN_EMAIL=admin@example.com
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
> **Note:** `GOOGLE_COOKIE_PASSWORD` encrypts session cookies. If omitted, an auto-generated value is used that doesn't survive server restarts. Set it explicitly for production.
|
|
37
|
+
>
|
|
38
|
+
> `MastraAuthGoogle` reads the `GOOGLE_*` auth variables automatically. The service-account variables shown above are read by the configuration code you pass to `MastraRBACGoogle`.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Before you can use the `MastraAuthGoogle` class, install the `@mastra/auth-google` package.
|
|
43
|
+
|
|
44
|
+
**npm**:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install @mastra/auth-google
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**pnpm**:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm add @mastra/auth-google
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Yarn**:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
yarn add @mastra/auth-google
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Bun**:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bun add @mastra/auth-google
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Usage examples
|
|
69
|
+
|
|
70
|
+
### Basic usage with environment variables
|
|
71
|
+
|
|
72
|
+
With the environment variables above set, all constructor parameters are optional:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { Mastra } from '@mastra/core'
|
|
76
|
+
import { MastraAuthGoogle } from '@mastra/auth-google'
|
|
77
|
+
|
|
78
|
+
export const mastra = new Mastra({
|
|
79
|
+
server: {
|
|
80
|
+
auth: new MastraAuthGoogle(),
|
|
81
|
+
},
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
> **Warning:** Use `allowedDomains` or `GOOGLE_ALLOWED_DOMAINS` to enforce Workspace access. Mastra checks Google's verified `hd` claim, not the email address suffix.
|
|
86
|
+
|
|
87
|
+
### Custom configuration
|
|
88
|
+
|
|
89
|
+
Pass constructor options directly if you don't want to rely on environment variables:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { Mastra } from '@mastra/core'
|
|
93
|
+
import { MastraAuthGoogle } from '@mastra/auth-google'
|
|
94
|
+
|
|
95
|
+
export const mastra = new Mastra({
|
|
96
|
+
server: {
|
|
97
|
+
auth: new MastraAuthGoogle({
|
|
98
|
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
|
99
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
100
|
+
redirectUri: process.env.GOOGLE_REDIRECT_URI,
|
|
101
|
+
allowedDomains: ['example.com'],
|
|
102
|
+
}),
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Auth with Google Groups RBAC
|
|
108
|
+
|
|
109
|
+
Add `MastraRBACGoogle` to map Google Workspace groups to Mastra permissions:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { Mastra } from '@mastra/core'
|
|
113
|
+
import { MastraAuthGoogle, MastraRBACGoogle } from '@mastra/auth-google'
|
|
114
|
+
|
|
115
|
+
export const mastra = new Mastra({
|
|
116
|
+
server: {
|
|
117
|
+
auth: new MastraAuthGoogle(),
|
|
118
|
+
rbac: new MastraRBACGoogle({
|
|
119
|
+
serviceAccount: {
|
|
120
|
+
clientEmail: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL!,
|
|
121
|
+
privateKey: process.env.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY!,
|
|
122
|
+
subject: process.env.GOOGLE_WORKSPACE_ADMIN_EMAIL!,
|
|
123
|
+
},
|
|
124
|
+
roleMapping: {
|
|
125
|
+
'admins@example.com': ['*'],
|
|
126
|
+
'engineering@example.com': ['agents:*', 'workflows:*', 'tools:*'],
|
|
127
|
+
'viewers@example.com': ['agents:read', 'workflows:read'],
|
|
128
|
+
_default: [], // users with unmapped groups get no permissions
|
|
129
|
+
},
|
|
130
|
+
}),
|
|
131
|
+
},
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Cross-provider usage
|
|
136
|
+
|
|
137
|
+
Use a different auth provider (Auth0, Clerk, etc.) for login and Google Workspace groups for RBAC. Pass a `getUserKey` function to resolve the Google Directory API user key from the other provider's user object:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { Mastra } from '@mastra/core'
|
|
141
|
+
import { MastraAuthAuth0 } from '@mastra/auth-auth0'
|
|
142
|
+
import { MastraRBACGoogle } from '@mastra/auth-google'
|
|
143
|
+
|
|
144
|
+
export const mastra = new Mastra({
|
|
145
|
+
server: {
|
|
146
|
+
auth: new MastraAuthAuth0(),
|
|
147
|
+
rbac: new MastraRBACGoogle({
|
|
148
|
+
getUserKey: user => {
|
|
149
|
+
if (!user || typeof user !== 'object') return undefined
|
|
150
|
+
|
|
151
|
+
const { email } = user as { email?: unknown }
|
|
152
|
+
return typeof email === 'string' ? email : undefined
|
|
153
|
+
},
|
|
154
|
+
serviceAccount: {
|
|
155
|
+
clientEmail: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL!,
|
|
156
|
+
privateKey: process.env.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY!,
|
|
157
|
+
subject: process.env.GOOGLE_WORKSPACE_ADMIN_EMAIL!,
|
|
158
|
+
},
|
|
159
|
+
roleMapping: {
|
|
160
|
+
'engineering@example.com': ['agents:*', 'workflows:*'],
|
|
161
|
+
'admins@example.com': ['*'],
|
|
162
|
+
_default: [],
|
|
163
|
+
},
|
|
164
|
+
}),
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
> **Info:** Visit [MastraAuthGoogle](https://mastra.ai/reference/auth/google) for all available configuration options.
|
|
170
|
+
|
|
171
|
+
## Role mapping
|
|
172
|
+
|
|
173
|
+
The `roleMapping` option maps Google Workspace group email addresses to arrays of Mastra permission strings. Permissions follow a `resource:action` pattern and support wildcards:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const rbac = new MastraRBACGoogle({
|
|
177
|
+
roleMapping: {
|
|
178
|
+
// full access to everything
|
|
179
|
+
'admins@example.com': ['*'],
|
|
180
|
+
|
|
181
|
+
// full access to agents and workflows
|
|
182
|
+
'engineering@example.com': ['agents:*', 'workflows:*'],
|
|
183
|
+
|
|
184
|
+
// read-only access
|
|
185
|
+
'viewers@example.com': ['agents:read', 'workflows:read'],
|
|
186
|
+
|
|
187
|
+
// users whose groups don't match any key above
|
|
188
|
+
_default: [],
|
|
189
|
+
},
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Group email addresses are used as role IDs by default. Use `mapGroupToRoles` if you want to map by group name or another property. The `_default` key assigns permissions to users whose Google Workspace groups don't match any other key.
|
|
194
|
+
|
|
195
|
+
## Client-side setup
|
|
196
|
+
|
|
197
|
+
When auth is enabled, requests to Mastra routes require authentication. When SSO is enabled with `GOOGLE_CLIENT_SECRET`, `MastraAuthGoogle` uses Google sign-in and sets an encrypted session cookie after login.
|
|
198
|
+
|
|
199
|
+
### Cookie session (recommended)
|
|
200
|
+
|
|
201
|
+
For cross-origin requests (for example, a frontend on `:3000` calling Mastra on `:4111`), enable CORS credentials on the Mastra server:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
export const mastra = new Mastra({
|
|
205
|
+
server: {
|
|
206
|
+
auth: new MastraAuthGoogle(),
|
|
207
|
+
cors: {
|
|
208
|
+
origin: 'http://localhost:3000',
|
|
209
|
+
credentials: true,
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Configure the client to include credentials:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import { MastraClient } from '@mastra/client-js'
|
|
219
|
+
|
|
220
|
+
export const mastraClient = new MastraClient({
|
|
221
|
+
baseUrl: 'http://localhost:4111',
|
|
222
|
+
credentials: 'include',
|
|
223
|
+
})
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Bearer token
|
|
227
|
+
|
|
228
|
+
You can also pass a Google ID token as a Bearer token. Mastra verifies the token against Google's JSON Web Key Set (JWKS) endpoint:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { MastraClient } from '@mastra/client-js'
|
|
232
|
+
|
|
233
|
+
export const createMastraClient = (idToken: string) => {
|
|
234
|
+
return new MastraClient({
|
|
235
|
+
baseUrl: 'http://localhost:4111',
|
|
236
|
+
headers: {
|
|
237
|
+
Authorization: `Bearer ${idToken}`,
|
|
238
|
+
},
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
> **Info:** Visit [Mastra Client SDK](https://mastra.ai/docs/server/mastra-client) for more configuration options.
|
|
244
|
+
|
|
245
|
+
### Making authenticated requests
|
|
246
|
+
|
|
247
|
+
**MastraClient**:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import { mastraClient } from '../lib/mastra-client'
|
|
251
|
+
|
|
252
|
+
const agent = mastraClient.getAgent('weatherAgent')
|
|
253
|
+
const response = await agent.generate('Weather in London')
|
|
254
|
+
console.log(response)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**cURL**:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
curl -X POST http://localhost:4111/api/agents/weatherAgent/generate \
|
|
261
|
+
-H "Content-Type: application/json" \
|
|
262
|
+
-H "Authorization: Bearer <your-google-id-token>" \
|
|
263
|
+
-d '{
|
|
264
|
+
"messages": "Weather in London"
|
|
265
|
+
}'
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Troubleshooting
|
|
269
|
+
|
|
270
|
+
- **401 after sign-in**: Check that `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, and `GOOGLE_REDIRECT_URI` match the Google Cloud OAuth client.
|
|
271
|
+
- **Workspace users are rejected**: Verify `GOOGLE_ALLOWED_DOMAINS` matches the Google ID token `hd` claim.
|
|
272
|
+
- **Consumer Gmail accounts are rejected**: This is expected when `allowedDomains` is configured because Gmail accounts don't have a Workspace `hd` claim.
|
|
273
|
+
- **RBAC returns default permissions**: No roles were resolved for the user. Verify the user email or custom `getUserKey`, Google group membership, and `roleMapping`. If the Directory API lookup fails, the provider throws an error instead of returning `_default`.
|
|
274
|
+
- **Cookies are not sent cross-origin**: Set `credentials: "include"` in `MastraClient` and configure `server.cors` with your frontend origin and `credentials: true`.
|
|
275
|
+
- **Session lost on restart**: Set `GOOGLE_COOKIE_PASSWORD` to a stable value of at least 32 characters. Without it, an auto-generated key is used in development and changes on each restart.
|
|
276
|
+
|
|
277
|
+
## Related
|
|
278
|
+
|
|
279
|
+
- [Auth overview](https://mastra.ai/docs/server/auth)
|
|
280
|
+
- [Composite Auth](https://mastra.ai/docs/server/auth/composite-auth)
|
|
281
|
+
- [MastraAuthGoogle reference](https://mastra.ai/reference/auth/google)
|
|
@@ -15,7 +15,7 @@ Authentication is optional. If no auth is configured, all routes and Studio are
|
|
|
15
15
|
|
|
16
16
|
See [Custom API Routes](https://mastra.ai/docs/server/custom-api-routes) for controlling authentication on custom endpoints. Visit the [Studio Auth docs](https://mastra.ai/docs/studio/auth) for more on securing your Studio deployment.
|
|
17
17
|
|
|
18
|
-
> **Note:** Authentication for Studio is currently supported by the following providers: Simple Auth, JWT, WorkOS,
|
|
18
|
+
> **Note:** Authentication for Studio is currently supported by the following providers: Simple Auth, JWT, WorkOS, Better Auth, and Google.
|
|
19
19
|
|
|
20
20
|
## Available providers
|
|
21
21
|
|
|
@@ -30,6 +30,7 @@ See [Custom API Routes](https://mastra.ai/docs/server/custom-api-routes) for con
|
|
|
30
30
|
- [Better Auth](https://mastra.ai/docs/server/auth/better-auth)
|
|
31
31
|
- [Clerk](https://mastra.ai/docs/server/auth/clerk)
|
|
32
32
|
- [Firebase](https://mastra.ai/docs/server/auth/firebase)
|
|
33
|
+
- [Google](https://mastra.ai/docs/server/auth/google)
|
|
33
34
|
- [Okta](https://mastra.ai/docs/server/auth/okta)
|
|
34
35
|
- [Supabase](https://mastra.ai/docs/server/auth/supabase)
|
|
35
36
|
- [WorkOS](https://mastra.ai/docs/server/auth/workos)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vercel
|
|
2
2
|
|
|
3
|
-
Vercel aggregates models from multiple providers with enhanced features like rate limiting and failover. Access
|
|
3
|
+
Vercel aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 293 models through Mastra's model router.
|
|
4
4
|
|
|
5
5
|
Learn more in the [Vercel documentation](https://ai-sdk.dev/providers/ai-sdk-providers).
|
|
6
6
|
|
|
@@ -267,6 +267,7 @@ ANTHROPIC_API_KEY=ant-...
|
|
|
267
267
|
| `perplexity/sonar-pro` |
|
|
268
268
|
| `perplexity/sonar-reasoning-pro` |
|
|
269
269
|
| `prodia/flux-fast-schnell` |
|
|
270
|
+
| `quiverai/arrow-1.1` |
|
|
270
271
|
| `recraft/recraft-v2` |
|
|
271
272
|
| `recraft/recraft-v3` |
|
|
272
273
|
| `recraft/recraft-v4` |
|
|
@@ -302,6 +303,7 @@ ANTHROPIC_API_KEY=ant-...
|
|
|
302
303
|
| `xai/grok-build-0.1` |
|
|
303
304
|
| `xai/grok-imagine-image` |
|
|
304
305
|
| `xai/grok-imagine-video` |
|
|
306
|
+
| `xai/grok-imagine-video-1.5` |
|
|
305
307
|
| `xai/grok-imagine-video-1.5-preview` |
|
|
306
308
|
| `xai/grok-stt` |
|
|
307
309
|
| `xai/grok-tts` |
|
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 4548 models from 134 providers through a single API.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -34,7 +34,7 @@ for await (const chunk of stream) {
|
|
|
34
34
|
|
|
35
35
|
| Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
|
|
36
36
|
| -------------------------------------------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
|
|
37
|
-
| `baseten/deepseek-ai/DeepSeek-V4-Pro` |
|
|
37
|
+
| `baseten/deepseek-ai/DeepSeek-V4-Pro` | 262K | | | | | | $2 | $3 |
|
|
38
38
|
| `baseten/moonshotai/Kimi-K2.5` | 262K | | | | | | $0.60 | $3 |
|
|
39
39
|
| `baseten/moonshotai/Kimi-K2.6` | 262K | | | | | | $0.95 | $4 |
|
|
40
40
|
| `baseten/moonshotai/Kimi-K2.7-Code` | 262K | | | | | | $0.95 | $4 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Fireworks AI
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 16 Fireworks AI models through Mastra's model router. Authentication is handled automatically using the `FIREWORKS_API_KEY` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [Fireworks AI documentation](https://fireworks.ai/docs/).
|
|
6
6
|
|
|
@@ -46,6 +46,7 @@ for await (const chunk of stream) {
|
|
|
46
46
|
| `fireworks-ai/accounts/fireworks/models/minimax-m3` | 512K | | | | | | $0.30 | $1 |
|
|
47
47
|
| `fireworks-ai/accounts/fireworks/models/qwen3p7-plus` | 262K | | | | | | $0.40 | $2 |
|
|
48
48
|
| `fireworks-ai/accounts/fireworks/routers/glm-5p1-fast` | 203K | | | | | | $3 | $9 |
|
|
49
|
+
| `fireworks-ai/accounts/fireworks/routers/glm-5p2-fast` | 1.0M | | | | | | $2 | $7 |
|
|
49
50
|
| `fireworks-ai/accounts/fireworks/routers/kimi-k2p6-fast` | 262K | | | | | | $2 | $8 |
|
|
50
51
|
| `fireworks-ai/accounts/fireworks/routers/kimi-k2p6-turbo` | 262K | | | | | | $2 | $8 |
|
|
51
52
|
| `fireworks-ai/accounts/fireworks/routers/kimi-k2p7-code-fast` | 262K | | | | | | $2 | $8 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Friendli
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 9 Friendli models through Mastra's model router. Authentication is handled automatically using the `FRIENDLI_TOKEN` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [Friendli documentation](https://friendli.ai/docs/guides/serverless_endpoints/introduction).
|
|
6
6
|
|
|
@@ -34,6 +34,8 @@ for await (const chunk of stream) {
|
|
|
34
34
|
|
|
35
35
|
| Model | Context | Tools | Reasoning | Image | Audio | Video | Input $/1M | Output $/1M |
|
|
36
36
|
| --------------------------------------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
|
|
37
|
+
| `friendli/deepseek-ai/DeepSeek-V3.2` | 164K | | | | | | $0.50 | $2 |
|
|
38
|
+
| `friendli/google/gemma-4-31B-it` | 262K | | | | | | $0.14 | $0.40 |
|
|
37
39
|
| `friendli/meta-llama/Llama-3.1-8B-Instruct` | 131K | | | | | | $0.10 | $0.10 |
|
|
38
40
|
| `friendli/meta-llama/Llama-3.3-70B-Instruct` | 131K | | | | | | $0.60 | $0.60 |
|
|
39
41
|
| `friendli/MiniMaxAI/MiniMax-M2.5` | 197K | | | | | | $0.30 | $1 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LLM Gateway
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 181 LLM Gateway models through Mastra's model router. Authentication is handled automatically using the `LLMGATEWAY_API_KEY` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [LLM Gateway documentation](https://llmgateway.io/docs).
|
|
6
6
|
|
|
@@ -159,7 +159,6 @@ for await (const chunk of stream) {
|
|
|
159
159
|
| `llmgateway/ministral-8b-2512` | 262K | | | | | | $0.15 | $0.15 |
|
|
160
160
|
| `llmgateway/mistral-large-2512` | 262K | | | | | | $0.50 | $2 |
|
|
161
161
|
| `llmgateway/mistral-large-latest` | 128K | | | | | | $4 | $12 |
|
|
162
|
-
| `llmgateway/mistral-ocr-latest` | — | | | | | | — | — |
|
|
163
162
|
| `llmgateway/mistral-small-2506` | 128K | | | | | | $0.10 | $0.30 |
|
|
164
163
|
| `llmgateway/nemotron-3-ultra-550b` | 262K | | | | | | $0.50 | $3 |
|
|
165
164
|
| `llmgateway/o1` | 200K | | | | | | $15 | $60 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Nebius Token Factory
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 19 Nebius Token Factory models through Mastra's model router. Authentication is handled automatically using the `NEBIUS_API_KEY` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [Nebius Token Factory documentation](https://docs.tokenfactory.nebius.com/).
|
|
6
6
|
|
|
@@ -52,6 +52,7 @@ for await (const chunk of stream) {
|
|
|
52
52
|
| `nebius/Qwen/Qwen3-Embedding-8B` | 33K | | | | | | $0.01 | — |
|
|
53
53
|
| `nebius/Qwen/Qwen3-Next-80B-A3B-Thinking` | 128K | | | | | | $0.15 | $1 |
|
|
54
54
|
| `nebius/Qwen/Qwen3.5-397B-A17B` | 262K | | | | | | $0.60 | $4 |
|
|
55
|
+
| `nebius/zai-org/GLM-5.2` | 432K | | | | | | $1 | $4 |
|
|
55
56
|
|
|
56
57
|
## Advanced configuration
|
|
57
58
|
|
|
@@ -81,7 +82,7 @@ const agent = new Agent({
|
|
|
81
82
|
model: ({ requestContext }) => {
|
|
82
83
|
const useAdvanced = requestContext.task === "complex";
|
|
83
84
|
return useAdvanced
|
|
84
|
-
? "nebius/
|
|
85
|
+
? "nebius/zai-org/GLM-5.2"
|
|
85
86
|
: "nebius/MiniMaxAI/MiniMax-M2.5";
|
|
86
87
|
}
|
|
87
88
|
});
|
|
@@ -43,7 +43,7 @@ for await (const chunk of stream) {
|
|
|
43
43
|
| `opencode-go/mimo-v2.5` | 1.0M | | | | | | $0.14 | $0.28 |
|
|
44
44
|
| `opencode-go/mimo-v2.5-pro` | 1.0M | | | | | | $2 | $3 |
|
|
45
45
|
| `opencode-go/minimax-m2.7` | 205K | | | | | | $0.30 | $1 |
|
|
46
|
-
| `opencode-go/minimax-m3` |
|
|
46
|
+
| `opencode-go/minimax-m3` | 1.0M | | | | | | $0.10 | $0.40 |
|
|
47
47
|
| `opencode-go/qwen3.6-plus` | 1.0M | | | | | | $0.50 | $3 |
|
|
48
48
|
| `opencode-go/qwen3.7-max` | 1.0M | | | | | | $3 | $8 |
|
|
49
49
|
| `opencode-go/qwen3.7-plus` | 1.0M | | | | | | $0.40 | $2 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# OVHcloud AI Endpoints
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 14 OVHcloud AI Endpoints models through Mastra's model router. Authentication is handled automatically using the `OVHCLOUD_API_KEY` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [OVHcloud AI Endpoints documentation](https://www.ovhcloud.com/en/public-cloud/ai-endpoints/catalog//).
|
|
6
6
|
|
|
@@ -36,7 +36,6 @@ for await (const chunk of stream) {
|
|
|
36
36
|
| ---------------------------------------------- | ------- | ----- | --------- | ----- | ----- | ----- | ---------- | ----------- |
|
|
37
37
|
| `ovhcloud/gpt-oss-120b` | 131K | | | | | | $0.09 | $0.47 |
|
|
38
38
|
| `ovhcloud/gpt-oss-20b` | 131K | | | | | | $0.05 | $0.18 |
|
|
39
|
-
| `ovhcloud/llama-3.1-8b-instruct` | 131K | | | | | | $0.11 | $0.11 |
|
|
40
39
|
| `ovhcloud/meta-llama-3_3-70b-instruct` | 131K | | | | | | $0.74 | $0.74 |
|
|
41
40
|
| `ovhcloud/mistral-7b-instruct-v0.3` | 66K | | | | | | $0.11 | $0.11 |
|
|
42
41
|
| `ovhcloud/mistral-nemo-instruct-2407` | 66K | | | | | | $0.14 | $0.14 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Scaleway
|
|
2
2
|
|
|
3
|
-
Access
|
|
3
|
+
Access 16 Scaleway models through Mastra's model router. Authentication is handled automatically using the `SCALEWAY_API_KEY` environment variable.
|
|
4
4
|
|
|
5
5
|
Learn more in the [Scaleway documentation](https://www.scaleway.com/en/docs/generative-apis/).
|
|
6
6
|
|
|
@@ -37,6 +37,7 @@ for await (const chunk of stream) {
|
|
|
37
37
|
| `scaleway/bge-multilingual-gemma2` | 8K | | | | | | $0.10 | — |
|
|
38
38
|
| `scaleway/gemma-3-27b-it` | 40K | | | | | | $0.25 | $0.50 |
|
|
39
39
|
| `scaleway/gemma-4-26b-a4b-it` | 256K | | | | | | $0.25 | $0.50 |
|
|
40
|
+
| `scaleway/glm-5.2` | 256K | | | | | | $2 | $6 |
|
|
40
41
|
| `scaleway/gpt-oss-120b` | 128K | | | | | | $0.15 | $0.60 |
|
|
41
42
|
| `scaleway/llama-3.3-70b-instruct` | 100K | | | | | | $0.90 | $0.90 |
|
|
42
43
|
| `scaleway/mistral-medium-3.5-128b` | 256K | | | | | | $2 | $8 |
|