# Integrate Mastra in Your NestJS Project In this guide, you'll build a tool-calling AI agent using Mastra and NestJS. The [NestJS server adapter](https://mastra.ai/reference/server/nestjs-adapter) registers Mastra's agent and workflow routes as a NestJS module, so they run inside your existing NestJS application. ## Before you begin - You'll need an API key from a supported [model provider](https://mastra.ai/models). If you don't have a preference, use [OpenAI](https://mastra.ai/models/providers/openai). - Install Node.js `v22.13.0` or later - Use the NestJS Express platform (`@nestjs/platform-express`) ## Create a new NestJS app (optional) If you already have a NestJS app, skip to the next step. Run the following command to create a new NestJS app: **npm**: ```bash npx @nestjs/cli new mastra-nest ``` **pnpm**: ```bash pnpm dlx @nestjs/cli new mastra-nest ``` **Yarn**: ```bash yarn dlx @nestjs/cli new mastra-nest ``` **Bun**: ```bash bun x @nestjs/cli new mastra-nest ``` This creates a project called `mastra-nest`, but you can replace it with any name you want. ## Initialize Mastra Navigate to your NestJS project directory: ```bash cd mastra-nest ``` Run [`mastra init`](https://mastra.ai/reference/cli/mastra). When prompted, choose a provider (e.g. OpenAI) and enter your key: **npm**: ```bash npx mastra@latest init ``` **pnpm**: ```bash pnpm dlx mastra@latest init ``` **Yarn**: ```bash yarn dlx mastra@latest init ``` **Bun**: ```bash bun x mastra@latest init ``` This creates a `src/mastra` folder with an example weather agent and the following files: - `index.ts` - Mastra config, including memory - `tools/weather-tool.ts` - a tool to fetch weather for a given location - `agents/weather-agent.ts` - a weather agent with a prompt that uses the tool You'll pass the `src/mastra/index.ts` file to the NestJS adapter in the next step. ## Add server adapter Install the NestJS server adapter package: **npm**: ```bash npm install @mastra/nestjs@latest ``` **pnpm**: ```bash pnpm add @mastra/nestjs@latest ``` **Yarn**: ```bash yarn add @mastra/nestjs@latest ``` **Bun**: ```bash bun add @mastra/nestjs@latest ``` Open `src/app.module.ts` and register `MastraModule`: ```typescript import { Module } from '@nestjs/common' import { MastraModule } from '@mastra/nestjs' import { mastra } from './mastra' @Module({ imports: [ MastraModule.register({ mastra, }), ], }) export class AppModule {} ``` > **Note:** `MastraModule` registers a catch-all controller (`@All('*')`). If it is imported before your app modules, it can intercept unrelated routes and return 404s. To avoid conflicts, import `MastraModule` last or mount it under a dedicated prefix (e.g., `/api/v1/mastra`). ## Test your agent By default, Mastra's endpoints are added under the `/api` subpath and use your agent/workflow IDs. The default `weather-agent` created by `mastra init` is available at `/api/agents/weather-agent`. Start your NestJS server: **npm**: ```bash npm run start ``` **pnpm**: ```bash pnpm run start ``` **Yarn**: ```bash yarn run start ``` **Bun**: ```bash bun run start ``` In a separate terminal window, use `curl` to ask the weather agent: ```bash curl -X POST http://localhost:3000/api/agents/weather-agent/generate -H "Content-Type: application/json" -d "{\"messages\":[{\"role\":\"user\",\"content\":\"What is the weather like in Seoul?\"}]}" ``` ## Use Mastra in Your Own Services The module exports two ways to access Mastra from your NestJS services: the `MastraService` wrapper and the `MASTRA` injection token. ### MastraService `MastraService` is an injectable wrapper with convenience methods for common operations: ```typescript import { Injectable } from '@nestjs/common' import { MastraService } from '@mastra/nestjs' @Injectable() export class AgentService { constructor(private readonly mastraService: MastraService) {} async chat(agentId: string, message: string) { const agent = this.mastraService.getAgent(agentId) return agent.generate({ messages: [{ role: 'user', content: message }], }) } async runWorkflow(workflowId: string, input: Record) { const workflow = this.mastraService.getWorkflow(workflowId) return workflow.start({ inputData: input }) } } ``` `MastraService` exposes: - `getMastra()` — returns the underlying `Mastra` instance - `getAgent(id)` — shorthand for `mastra.getAgent(id)` - `getWorkflow(id)` — shorthand for `mastra.getWorkflow(id)` - `getOptions()` — returns the module configuration - `isShuttingDown` — `true` after graceful shutdown begins ### MASTRA token If you need the `Mastra` instance directly (e.g., to access storage, memory, or other core APIs), inject it with the `MASTRA` token: ```typescript import { Injectable, Inject } from '@nestjs/common' import { MASTRA } from '@mastra/nestjs' import type { Mastra } from '@mastra/core/mastra' @Injectable() export class MemoryService { constructor(@Inject(MASTRA) private readonly mastra: Mastra) {} async getThreadMessages(threadId: string) { const memory = this.mastra.getMemory() return memory?.getMessages({ threadId }) } } ``` Both approaches use the same singleton `Mastra` instance registered by `MastraModule`. ## Next steps You now have a working Mastra agent running inside NestJS. To extend the project: - [Agents overview](https://mastra.ai/docs/agents/overview) - [Using tools](https://mastra.ai/docs/agents/using-tools) - [Agent memory](https://mastra.ai/docs/memory/overview) For details on the NestJS integration: - [NestJS Adapter reference](https://mastra.ai/reference/server/nestjs-adapter)