@mastra/nestjs 0.2.23-alpha.6 → 0.2.23-alpha.8
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/README.md +23 -288
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -1,66 +1,36 @@
|
|
|
1
1
|
# @mastra/nestjs
|
|
2
2
|
|
|
3
|
-
NestJS server adapter for [Mastra](https://mastra.ai). Use it to expose agents, workflows, tools, MCP, and streaming endpoints through NestJS with native guards, interceptors, and
|
|
3
|
+
NestJS server adapter for [Mastra](https://mastra.ai). Use it to expose agents, workflows, tools, MCP, memory, voice, and streaming endpoints through NestJS with native dependency injection, guards, interceptors, and exception handling.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **NestJS-native integration** via modules, DI, guards, interceptors, and filters
|
|
10
|
-
- **Rate limiting** enabled by default (opt-out)
|
|
11
|
-
- **Graceful shutdown** with in-flight request tracking and optional SSE notifications
|
|
12
|
-
- **Streaming** for AI responses with optional redaction and SSE heartbeats
|
|
13
|
-
- **MCP transport** (HTTP + SSE) exposed under the API prefix
|
|
5
|
+
The adapter supports NestJS running on the Express platform. If an application uses the Fastify platform, `MastraModule` fails during bootstrap instead of partially initializing.
|
|
14
6
|
|
|
15
7
|
## Installation
|
|
16
8
|
|
|
17
9
|
```bash
|
|
18
|
-
npm install @mastra/nestjs
|
|
19
|
-
# or
|
|
20
|
-
pnpm add @mastra/nestjs @mastra/core
|
|
21
|
-
# or
|
|
22
|
-
yarn add @mastra/nestjs @mastra/core
|
|
10
|
+
npm install @mastra/nestjs
|
|
23
11
|
```
|
|
24
12
|
|
|
25
|
-
##
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
Register `MastraModule` in the application module. Import it after modules with application routes so its catch-all controller does not intercept them first.
|
|
26
16
|
|
|
27
|
-
```typescript
|
|
28
|
-
// app.module.ts
|
|
17
|
+
```typescript title="src/app.module.ts"
|
|
29
18
|
import { Module } from '@nestjs/common';
|
|
30
19
|
import { MastraModule } from '@mastra/nestjs';
|
|
31
|
-
import {
|
|
32
|
-
import { z } from 'zod';
|
|
33
|
-
import { createTool } from '@mastra/core/tools';
|
|
34
|
-
|
|
35
|
-
/** Simple tool used by the demo agent. */
|
|
36
|
-
const pingTool = createTool({
|
|
37
|
-
id: 'ping',
|
|
38
|
-
description: 'Returns a pong response',
|
|
39
|
-
inputSchema: z.object({ message: z.string() }),
|
|
40
|
-
execute: async ({ message }) => ({ ok: true, message }),
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
/** Minimal Mastra instance for NestJS integration. */
|
|
44
|
-
const mastra = new Mastra({
|
|
45
|
-
tools: { ping: pingTool },
|
|
46
|
-
agents: {
|
|
47
|
-
greeter: {
|
|
48
|
-
name: 'greeter',
|
|
49
|
-
description: 'Greets the user and can call tools.',
|
|
50
|
-
model: 'openai/gpt-4o-mini',
|
|
51
|
-
tools: ['ping'],
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
});
|
|
20
|
+
import { mastra } from './mastra';
|
|
55
21
|
|
|
56
22
|
@Module({
|
|
57
|
-
imports: [
|
|
23
|
+
imports: [
|
|
24
|
+
MastraModule.register({
|
|
25
|
+
mastra,
|
|
26
|
+
prefix: '/api/mastra',
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
58
29
|
})
|
|
59
30
|
export class AppModule {}
|
|
60
31
|
```
|
|
61
32
|
|
|
62
|
-
```typescript
|
|
63
|
-
// main.ts
|
|
33
|
+
```typescript title="src/main.ts"
|
|
64
34
|
import { NestFactory } from '@nestjs/core';
|
|
65
35
|
import { AppModule } from './app.module';
|
|
66
36
|
|
|
@@ -72,253 +42,18 @@ async function bootstrap() {
|
|
|
72
42
|
bootstrap();
|
|
73
43
|
```
|
|
74
44
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
## Async Module Registration
|
|
78
|
-
|
|
79
|
-
Use async registration when the Mastra config depends on runtime services (e.g., `ConfigService`).
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import { Module } from '@nestjs/common';
|
|
83
|
-
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
84
|
-
import { MastraModule } from '@mastra/nestjs';
|
|
85
|
-
import { Mastra } from '@mastra/core/mastra';
|
|
86
|
-
|
|
87
|
-
@Module({
|
|
88
|
-
imports: [
|
|
89
|
-
ConfigModule.forRoot(),
|
|
90
|
-
MastraModule.registerAsync({
|
|
91
|
-
imports: [ConfigModule],
|
|
92
|
-
useFactory: (config: ConfigService) => ({
|
|
93
|
-
mastra: new Mastra({
|
|
94
|
-
agents: {
|
|
95
|
-
greeter: {
|
|
96
|
-
name: 'greeter',
|
|
97
|
-
description: 'Greets users with a short response.',
|
|
98
|
-
model: config.get('MASTRA_MODEL', 'openai/gpt-4o-mini'),
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
}),
|
|
102
|
-
prefix: config.get('MASTRA_PREFIX', '/api'),
|
|
103
|
-
}),
|
|
104
|
-
inject: [ConfigService],
|
|
105
|
-
}),
|
|
106
|
-
],
|
|
107
|
-
})
|
|
108
|
-
export class AppModule {}
|
|
109
|
-
```
|
|
45
|
+
## Documentation
|
|
110
46
|
|
|
111
|
-
|
|
47
|
+
`MastraModule.register()` accepts the Mastra instance and optional settings for the route prefix, rate limits, graceful shutdown, request body limits, stream heartbeat and redaction, tracing, request context parsing, tools, MCP transport, authentication, and per-route auth overrides.
|
|
112
48
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
import { Injectable, Inject } from '@nestjs/common';
|
|
117
|
-
import { MASTRA, MastraService } from '@mastra/nestjs';
|
|
118
|
-
import type { Mastra } from '@mastra/core/mastra';
|
|
119
|
-
|
|
120
|
-
@Injectable()
|
|
121
|
-
export class AgentService {
|
|
122
|
-
constructor(@Inject(MASTRA) private readonly mastra: Mastra) {}
|
|
123
|
-
|
|
124
|
-
async greet() {
|
|
125
|
-
const agent = this.mastra.getAgent('greeter');
|
|
126
|
-
return agent.generate({
|
|
127
|
-
messages: [{ role: 'user', content: 'Hello from NestJS' }],
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
@Injectable()
|
|
133
|
-
export class WorkflowService {
|
|
134
|
-
constructor(private readonly mastraService: MastraService) {}
|
|
135
|
-
|
|
136
|
-
async runWorkflow(workflowId: string, inputData: Record<string, unknown>) {
|
|
137
|
-
const workflow = this.mastraService.getWorkflow(workflowId);
|
|
138
|
-
return workflow.start({ inputData });
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## Request Context (GET + POST)
|
|
144
|
-
|
|
145
|
-
Pass request context via query string or JSON body. The adapter accepts JSON or base64-encoded JSON.
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
curl "http://localhost:3000/api/agents/greeter/generate?requestContext=%7B%22userId%22%3A%22123%22%7D"
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
```bash
|
|
152
|
-
curl -X POST "http://localhost:3000/api/agents/greeter/generate" \
|
|
153
|
-
-H "Content-Type: application/json" \
|
|
154
|
-
-d '{"messages":[{"role":"user","content":"hi"}],"requestContext":{"userId":"123"}}'
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Rate Limiting
|
|
158
|
-
|
|
159
|
-
Rate limiting is on by default. Disable it or customize limits:
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
MastraModule.register({
|
|
163
|
-
mastra,
|
|
164
|
-
rateLimitOptions: {
|
|
165
|
-
enabled: true,
|
|
166
|
-
defaultLimit: 200,
|
|
167
|
-
generateLimit: 20,
|
|
168
|
-
windowMs: 60_000,
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
```
|
|
49
|
+
The module registers Mastra routes under `/api` by default. Because it uses a catch-all NestJS controller, either import `MastraModule` last or assign a dedicated prefix such as `/api/mastra`.
|
|
172
50
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
Mastra's built-in token auth is disabled by default because most NestJS apps already have their own auth layer. When enabled, bearer tokens from the `Authorization` header are the default credential source.
|
|
176
|
-
|
|
177
|
-
Query-string `?apiKey=` auth is available only as an explicit backward-compatibility option:
|
|
178
|
-
|
|
179
|
-
```typescript
|
|
180
|
-
MastraModule.register({
|
|
181
|
-
mastra,
|
|
182
|
-
auth: {
|
|
183
|
-
enabled: true,
|
|
184
|
-
allowQueryApiKey: true,
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## Streaming Options
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
MastraModule.register({
|
|
193
|
-
mastra,
|
|
194
|
-
streamOptions: {
|
|
195
|
-
redact: true,
|
|
196
|
-
heartbeatMs: 20_000,
|
|
197
|
-
},
|
|
198
|
-
});
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## MCP Transport (HTTP + SSE)
|
|
202
|
-
|
|
203
|
-
MCP endpoints are exposed under the API prefix:
|
|
204
|
-
|
|
205
|
-
- `POST /api/mcp/:serverId/mcp`
|
|
206
|
-
- `GET /api/mcp/:serverId/sse`
|
|
207
|
-
- `POST /api/mcp/:serverId/messages`
|
|
208
|
-
|
|
209
|
-
## Health Endpoints
|
|
210
|
-
|
|
211
|
-
These are always at the root (not under the prefix):
|
|
212
|
-
|
|
213
|
-
- `GET /health`
|
|
214
|
-
- `GET /ready`
|
|
215
|
-
- `GET /info`
|
|
216
|
-
|
|
217
|
-
## Decorators
|
|
218
|
-
|
|
219
|
-
Skip auth or rate limiting on specific controller routes:
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
import { Controller, Get, Post } from '@nestjs/common';
|
|
223
|
-
import { Public, SkipThrottle, MastraThrottle } from '@mastra/nestjs';
|
|
224
|
-
|
|
225
|
-
@Controller('custom')
|
|
226
|
-
export class CustomController {
|
|
227
|
-
@Get('public')
|
|
228
|
-
@Public()
|
|
229
|
-
publicRoute() {}
|
|
230
|
-
|
|
231
|
-
@Get('unlimited')
|
|
232
|
-
@SkipThrottle()
|
|
233
|
-
unlimitedRoute() {}
|
|
234
|
-
|
|
235
|
-
@Post('custom-limit')
|
|
236
|
-
@MastraThrottle({ limit: 5, windowMs: 60_000 })
|
|
237
|
-
customLimitRoute() {}
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## Configuration Options
|
|
242
|
-
|
|
243
|
-
| Option | Type | Default | Description |
|
|
244
|
-
| ----------------------------------- | --------------------------------------------------- | -------------------- | ------------------------------------------- |
|
|
245
|
-
| `mastra` | `Mastra` | required | The Mastra instance |
|
|
246
|
-
| `prefix` | `string` | `/api` | Route prefix |
|
|
247
|
-
| `rateLimitOptions` | `object` | enabled | Rate limiting configuration |
|
|
248
|
-
| `rateLimitOptions.enabled` | `boolean` | `true` | Enable/disable rate limiting |
|
|
249
|
-
| `rateLimitOptions.defaultLimit` | `number` | `100` | Requests per window |
|
|
250
|
-
| `rateLimitOptions.generateLimit` | `number` | `10` | Stricter limit for `/generate` |
|
|
251
|
-
| `rateLimitOptions.windowMs` | `number` | `60000` | Window size in ms |
|
|
252
|
-
| `shutdownOptions` | `object` | - | Graceful shutdown configuration |
|
|
253
|
-
| `shutdownOptions.timeoutMs` | `number` | `30000` | Max wait time for in-flight requests |
|
|
254
|
-
| `shutdownOptions.notifyClients` | `boolean` | `true` | Send shutdown event to SSE clients |
|
|
255
|
-
| `bodyLimitOptions` | `object` | - | Request body size limits |
|
|
256
|
-
| `bodyLimitOptions.maxSize` | `number` | `10MB` | Max JSON body size |
|
|
257
|
-
| `bodyLimitOptions.maxFileSize` | `number` | - | Max multipart file size (no limit if unset) |
|
|
258
|
-
| `bodyLimitOptions.allowedMimeTypes` | `string[]` | - | Allowed upload MIME types |
|
|
259
|
-
| `streamOptions` | `{ redact?: boolean; heartbeatMs?: number }` | - | Streaming config |
|
|
260
|
-
| `tracingOptions` | `{ enabled?: boolean; serviceName?: string }` | - | OpenTelemetry tracing |
|
|
261
|
-
| `customRouteAuthConfig` | `Map<string, boolean>` | - | Per-route auth overrides |
|
|
262
|
-
| `mcpOptions` | `object` | - | MCP transport options |
|
|
263
|
-
| `mcpOptions.serverless` | `boolean` | `false` | Stateless MCP HTTP mode |
|
|
264
|
-
| `mcpOptions.sessionIdGenerator` | `() => string` | - | Custom MCP session IDs |
|
|
265
|
-
| `auth` | `{ enabled?: boolean; allowQueryApiKey?: boolean }` | `{ enabled: false }` | Enable Mastra's built-in token auth |
|
|
266
|
-
|
|
267
|
-
## Requirements
|
|
268
|
-
|
|
269
|
-
- Node.js >= 22.13.0
|
|
270
|
-
- NestJS with Express adapter (`@nestjs/platform-express`)
|
|
271
|
-
- Express 4.x or 5.x
|
|
272
|
-
|
|
273
|
-
**Note:** This adapter supports NestJS with Express only. Fastify is not supported in v1, and `MastraModule` throws during bootstrap if another Nest HTTP adapter is in use.
|
|
274
|
-
|
|
275
|
-
## API Reference
|
|
276
|
-
|
|
277
|
-
### `MastraModule.register(options)`
|
|
278
|
-
|
|
279
|
-
Register Mastra with NestJS DI.
|
|
280
|
-
|
|
281
|
-
### `MastraModule.registerAsync(options)`
|
|
282
|
-
|
|
283
|
-
Async registration supporting `useFactory`, `useClass`, and `useExisting`.
|
|
284
|
-
|
|
285
|
-
### `MastraService`
|
|
286
|
-
|
|
287
|
-
```typescript
|
|
288
|
-
class MastraService {
|
|
289
|
-
getMastra(): Mastra;
|
|
290
|
-
getOptions(): MastraModuleOptions;
|
|
291
|
-
getAgent(agentId: string): Agent;
|
|
292
|
-
getWorkflow(workflowId: string): Workflow;
|
|
293
|
-
isShuttingDown: boolean;
|
|
294
|
-
}
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### `MASTRA`
|
|
298
|
-
|
|
299
|
-
Injection token for the Mastra instance.
|
|
300
|
-
|
|
301
|
-
## Exported Components
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
import {
|
|
305
|
-
MastraAuthGuard,
|
|
306
|
-
MastraThrottleGuard,
|
|
307
|
-
StreamingInterceptor,
|
|
308
|
-
RequestTrackingInterceptor,
|
|
309
|
-
MastraExceptionFilter,
|
|
310
|
-
RouteHandlerService,
|
|
311
|
-
RequestContextService,
|
|
312
|
-
ShutdownService,
|
|
313
|
-
} from '@mastra/nestjs';
|
|
314
|
-
```
|
|
51
|
+
- [NestJS adapter reference](https://mastra.ai/reference/server/nestjs-adapter)
|
|
315
52
|
|
|
316
|
-
##
|
|
53
|
+
## Changelog
|
|
317
54
|
|
|
318
|
-
|
|
319
|
-
- [@mastra/express](https://www.npmjs.com/package/@mastra/express)
|
|
320
|
-
- [@mastra/hono](https://www.npmjs.com/package/@mastra/hono)
|
|
55
|
+
See the [package changelog](https://github.com/mastra-ai/mastra/blob/main/server-adapters/nestjs/CHANGELOG.md) for version history and release notes.
|
|
321
56
|
|
|
322
|
-
##
|
|
57
|
+
## Support
|
|
323
58
|
|
|
324
|
-
|
|
59
|
+
We have an [open community Discord](https://discord.gg/mastra-ai). Come and say hello and let us know if you have any questions or need any help getting things running.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/nestjs",
|
|
3
|
-
"version": "0.2.23-alpha.
|
|
3
|
+
"version": "0.2.23-alpha.8",
|
|
4
4
|
"description": "Mastra NestJS adapter for the server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@fastify/busboy": "^3.2.0",
|
|
24
|
-
"@mastra/server": "1.64.0-alpha.
|
|
24
|
+
"@mastra/server": "1.64.0-alpha.8"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@ai-sdk/openai": "^2.0.115",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"vitest": "^4.1.10",
|
|
45
45
|
"zod": "^3.25.0",
|
|
46
46
|
"@internal/lint": "0.0.129",
|
|
47
|
-
"@internal/storage-test-utils": "0.0.125",
|
|
48
|
-
"@internal/types-builder": "0.0.104",
|
|
49
|
-
"@mastra/core": "1.64.0-alpha.6",
|
|
50
|
-
"@mastra/memory": "1.28.2-alpha.1",
|
|
51
|
-
"@mastra/evals": "1.10.0-alpha.0",
|
|
52
|
-
"@mastra/observability": "1.17.5-alpha.0",
|
|
53
47
|
"@internal/server-adapter-test-utils": "0.0.29",
|
|
54
|
-
"@
|
|
48
|
+
"@internal/types-builder": "0.0.104",
|
|
49
|
+
"@internal/storage-test-utils": "0.0.125",
|
|
50
|
+
"@mastra/evals": "1.10.0-alpha.1",
|
|
51
|
+
"@mastra/core": "1.64.0-alpha.8",
|
|
52
|
+
"@mastra/memory": "1.28.2-alpha.3",
|
|
53
|
+
"@mastra/libsql": "1.22.3-alpha.3",
|
|
54
|
+
"@mastra/observability": "1.17.5-alpha.2"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"@mastra/core": ">=1.50.0-0 <2.0.0-0",
|