# MongoDB Storage

The MongoDB storage implementation provides a scalable storage solution using MongoDB databases with support for both document storage and vector operations.

## Installation

**npm**:

```bash
npm install @mastra/mongodb@latest
```

**pnpm**:

```bash
pnpm add @mastra/mongodb@latest
```

**Yarn**:

```bash
yarn add @mastra/mongodb@latest
```

**Bun**:

```bash
bun add @mastra/mongodb@latest
```

## Usage

Ensure you have a MongoDB Atlas Local (via Docker) or MongoDB Atlas Cloud instance with Atlas Search enabled. MongoDB 7.0+ is recommended.

```typescript
import { MongoDBStore } from "@mastra/mongodb";

const storage = new MongoDBStore({
  id: 'mongodb-storage',
  uri: process.env.MONGODB_URI,
  dbName: process.env.MONGODB_DATABASE,
});
```

## Parameters

**id:** (`string`): Unique identifier for this storage instance.

**uri:** (`string`): MongoDB connection string (e.g., mongodb+srv://user:password\@cluster.mongodb.net)

**url?:** (`string`): Deprecated. Use uri instead. MongoDB connection string (supported for backward compatibility).

**dbName:** (`string`): The name of the database you want the storage to use.

**options?:** (`MongoClientOptions`): MongoDB client options for advanced configuration (SSL, connection pooling, etc.).

> **Deprecation Notice:** The `url` parameter is deprecated but still supported for backward compatibility. Please use `uri` instead in all new code.

## Constructor Examples

You can instantiate `MongoDBStore` in the following ways:

```ts
import { MongoDBStore } from "@mastra/mongodb";

// Basic connection without custom options
const store1 = new MongoDBStore({
  id: 'mongodb-storage-01',
  uri: "mongodb+srv://user:password@cluster.mongodb.net",
  dbName: "mastra_storage",
});

// Using connection string with options
const store2 = new MongoDBStore({
  id: 'mongodb-storage-02',
  uri: "mongodb+srv://user:password@cluster.mongodb.net",
  dbName: "mastra_storage",
  options: {
    retryWrites: true,
    maxPoolSize: 10,
    serverSelectionTimeoutMS: 5000,
    socketTimeoutMS: 45000,
  },
});
```

## Additional Notes

### Collection Management

The storage implementation handles collection creation and management automatically. It creates the following collections:

- `mastra_workflow_snapshot`: Stores workflow state and execution data
- `mastra_evals`: Stores evaluation results and metadata
- `mastra_threads`: Stores conversation threads
- `mastra_messages`: Stores individual messages
- `mastra_traces`: Stores telemetry and tracing data
- `mastra_scorers`: Stores scoring and evaluation data
- `mastra_resources`: Stores resource working memory data

### Initialization

When you pass storage to the Mastra class, `init()` is called automatically before any storage operation:

```typescript
import { Mastra } from "@mastra/core";
import { MongoDBStore } from "@mastra/mongodb";

const storage = new MongoDBStore({
  id: 'mongodb-storage',
  uri: process.env.MONGODB_URI,
  dbName: process.env.MONGODB_DATABASE,
});

const mastra = new Mastra({
  storage, // init() is called automatically
});
```

If you're using storage directly without Mastra, you must call `init()` explicitly to create the collections:

```typescript
import { MongoDBStore } from "@mastra/mongodb";

const storage = new MongoDBStore({
  id: 'mongodb-storage',
  uri: process.env.MONGODB_URI,
  dbName: process.env.MONGODB_DATABASE,
});

// Required when using storage directly
await storage.init();

// Access domain-specific stores via getStore()
const memoryStore = await storage.getStore('memory');
const thread = await memoryStore?.getThreadById({ threadId: "..." });
```

> **Warning:** If `init()` is not called, collections won't be created and storage operations will fail silently or throw errors.

## Vector Search Capabilities

MongoDB storage includes built-in vector search capabilities for AI applications:

### Vector Index Creation

```typescript
import { MongoDBVector } from "@mastra/mongodb";

const vectorStore = new MongoDBVector({
  id: 'mongodb-vector',
  uri: process.env.MONGODB_URI,
  dbName: process.env.MONGODB_DATABASE,
});

// Create a vector index for embeddings
await vectorStore.createIndex({
  indexName: "document_embeddings",
  dimension: 1536,
});
```

### Vector Operations

```typescript
// Store vectors with metadata
await vectorStore.upsert({
  indexName: "document_embeddings",
  vectors: [
    {
      id: "doc-1",
      values: [0.1, 0.2, 0.3, ...], // 1536-dimensional vector
      metadata: {
        title: "Document Title",
        category: "technical",
        source: "api-docs",
      },
    },
  ],
});

// Similarity search
const results = await vectorStore.query({
  indexName: "document_embeddings",
  vector: queryEmbedding,
  topK: 5,
  filter: {
    category: "technical",
  },
});
```

## Usage Example

### Adding memory to an agent

To add MongoDB memory to an agent use the `Memory` class and create a new `storage` key using `MongoDBStore`. The configuration supports both local and remote MongoDB instances.

```typescript
import { Memory } from "@mastra/memory";
import { Agent } from "@mastra/core/agent";
import { MongoDBStore } from "@mastra/mongodb";

export const mongodbAgent = new Agent({
  id: "mongodb-agent",
  name: "mongodb-agent",
  instructions:
    "You are an AI agent with the ability to automatically recall memories from previous interactions.",
  model: "openai/gpt-5.1",
  memory: new Memory({
    storage: new MongoDBStore({
      uri: process.env.MONGODB_URI!,
      dbName: process.env.MONGODB_DB_NAME!,
    }),
    options: {
      generateTitle: true,
    },
  }),
});
```

### Using the agent

Use `memoryOptions` to scope recall for this request. Set `lastMessages: 5` to limit recency-based recall, and use `semanticRecall` to fetch the `topK: 3` most relevant messages, including `messageRange: 2` neighboring messages for context around each match.

```typescript
import "dotenv/config";

import { mastra } from "./mastra";

const threadId = "123";
const resourceId = "user-456";

const agent = mastra.getAgent("mongodbAgent");

const message = await agent.stream("My name is Mastra", {
  memory: {
    thread: threadId,
    resource: resourceId,
  },
});

await message.textStream.pipeTo(new WritableStream());

const stream = await agent.stream("What's my name?", {
  memory: {
    thread: threadId,
    resource: resourceId,
  },
  memoryOptions: {
    lastMessages: 5,
    semanticRecall: {
      topK: 3,
      messageRange: 2,
    },
  },
});

for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}
```