npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mastra-azure-ai-search

v0.1.0

Published

Azure AI Search vector store provider for Mastra

Readme

mastra-azure-ai-search

Azure AI Search vector store provider for Mastra. This package provides vector storage and similarity search capabilities using Azure AI Search's vector search features.

Installation

npm install mastra-azure-ai-search
# or
pnpm add mastra-azure-ai-search
# or
yarn add mastra-azure-ai-search

Community Demo

A public demo using this package is available at:

  • https://github.com/valdepeace/mastra-azure-aisearch-demo

Use it as a reference for end-to-end setup and usage with Azure AI Search.

Upstream Context

This package tracks the Azure AI Search vector store work proposed for Mastra in mastra-ai/mastra#10146.

Publishing

This package is intended to be published independently from the Mastra monorepo.

pnpm install --ignore-workspace
pnpm build
pnpm publish --access public

Prerequisites

Before using this package, you'll need:

  1. Azure AI Search service: Create an Azure AI Search service in your Azure subscription
  2. API Key or Azure credentials: Get your API key from the Azure portal or use Azure authentication
  3. Service endpoint: The URL of your Azure AI Search service (e.g., https://your-service.search.windows.net)

Configuration

Basic Setup with API Key

import { AzureAISearchVector } from 'mastra-azure-ai-search';

const azureVector = new AzureAISearchVector({
  id: 'azure-search-vectors',
  endpoint: 'https://your-service.search.windows.net',
  credential: 'your-api-key'
});

Setup with Azure Credentials

import { AzureAISearchVector } from 'mastra-azure-ai-search';
import { DefaultAzureCredential } from '@azure/identity';

const azureVector = new AzureAISearchVector({
  id: 'azure-search-vectors',
  endpoint: 'https://your-service.search.windows.net',
  credential: new DefaultAzureCredential()
});

Advanced Client Configuration

Use clientOptions to customize the SearchClient behavior with retry policies, custom headers, or proxy configurations:

import { AzureAISearchVector } from 'mastra-azure-ai-search';

const azureVector = new AzureAISearchVector({
  id: 'azure-search-custom',
  endpoint: 'https://your-service.search.windows.net',
  credential: 'your-api-key',
  clientOptions: {
    // Add custom policies (e.g., for proxy, logging, etc.)
    additionalPolicies: [
      {
        position: 'perCall',
        policy: {
          name: 'CustomHeadersPolicy',
          async sendRequest(request, next) {
            // Add custom headers
            request.headers.set('X-Custom-Header', 'my-value');
            return next(request);
          }
        }
      }
    ],
    // Configure retry behavior
    retryOptions: {
      maxRetries: 3,
      retryDelayInMs: 1000
    }
  }
});

Example: Using with a Proxy

import { AzureAISearchVector } from 'mastra-azure-ai-search';
import type { PipelinePolicy } from '@azure/core-rest-pipeline';

// Custom proxy policy
const createProxyPolicy = (config: {
  proxyUrl: string;
  token: string;
}): PipelinePolicy => ({
  name: 'ProxyPolicy',
  async sendRequest(request, next) {
    // Rewrite URL to proxy
    const originalUrl = new URL(request.url);
    request.url = `${config.proxyUrl}${originalUrl.pathname}${originalUrl.search}`;
    
    // Add proxy authentication
    request.headers.set('Authorization', `Bearer ${config.token}`);
    
    return next(request);
  }
});

const azureVector = new AzureAISearchVector({
  id: 'azure-search-proxy',
  endpoint: 'https://your-service.search.windows.net',
  credential: 'dummy-key', // Not used with proxy
  clientOptions: {
    additionalPolicies: [{
      position: 'perCall',
      policy: createProxyPolicy({
        proxyUrl: 'https://my-proxy.example.com',
        token: process.env.PROXY_TOKEN!
      })
    }]
  }
});

Integration with Mastra Memory System

import { openai } from '@ai-sdk/openai';
import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { AzureAISearchVector } from 'mastra-azure-ai-search';

// Setup Azure AI Search vector store
const azureVector = new AzureAISearchVector({
  id: 'azure-memory-store',
  endpoint: process.env.AZURE_AI_SEARCH_ENDPOINT!,
  credential: process.env.AZURE_AI_SEARCH_CREDENTIAL!,
});

// Configure Memory with Azure AI Search
const memory = new Memory({
  vector: azureVector,
  options: {
    lastMessages: 15,
    semanticRecall: {
      topK: 5,
      messageRange: 3,
    },
  },
  embedder: openai.embedding('text-embedding-3-small'),
});

// Create agent with advanced memory
const agent = new Agent({
  id: 'azure-assistant',
  name: 'Azure-Powered Assistant',
  instructions: 'You are an assistant with advanced memory capabilities powered by Azure AI Search.',
  model: openai('gpt-4o'),
  memory,
});

Basic Vector Store Setup

import { Mastra } from '@mastra/core';
import { AzureAISearchVector } from 'mastra-azure-ai-search';

const azureVector = new AzureAISearchVector({
  id: 'azure-search',
  endpoint: process.env.AZURE_AI_SEARCH_ENDPOINT!,
  credential: process.env.AZURE_AI_SEARCH_CREDENTIAL!
});

const mastra = new Mastra({
  vectors: {
    'azure-search': azureVector
  }
});

Usage Examples

Creating an Index

// Create a new vector index
await azureVector.createIndex({
  indexName: 'products',
  dimension: 1536, // Vector dimension (e.g., for OpenAI embeddings)
  metric: 'cosine' // Similarity metric: 'cosine', 'euclidean', or 'dotproduct'
});

Add explicit fields when you need Azure AI Search to filter on values that also live in Mastra metadata:

await azureVector.createIndex({
  indexName: 'products',
  dimension: 1536,
  additionalFields: [
    { name: 'category', type: 'Edm.String', filterable: true },
    { name: 'price', type: 'Edm.Double', filterable: true },
    { name: 'inStock', type: 'Edm.Boolean', filterable: true },
  ],
});

Mastra Memory passes metadataIndexes when creating semantic recall indexes. This adapter maps those metadata indexes to filterable Azure AI Search string fields:

await azureVector.createIndex({
  indexName: 'memory_messages',
  dimension: 1536,
  metadataIndexes: ['thread_id', 'resource_id'],
});

Inserting Vectors

// Insert vectors with metadata
const vectorIds = await azureVector.upsert({
  indexName: 'products',
  vectors: [
    [0.1, 0.2, 0.3 /* ...1536 dimensions */], // Vector 1
    [0.4, 0.5, 0.6 /* ...1536 dimensions */], // Vector 2
  ],
  metadata: [
    { 
      category: 'electronics', 
      brand: 'Apple', 
      price: 999,
      content: 'iPhone 15 Pro Max with advanced camera system'
    },
    { 
      category: 'electronics', 
      brand: 'Samsung', 
      price: 899,
      content: 'Galaxy S24 Ultra with S Pen and AI features'
    }
  ],
  ids: ['iphone-15-pro', 'galaxy-s24-ultra'] // Optional: provide custom IDs
});

console.log('Inserted vector IDs:', vectorIds);

The full metadata object is stored in the metadata JSON string. Values with keys that match explicit Azure index fields are also written to those fields so they can be filtered by Azure AI Search.

Searching Vectors

Basic Vector Search

const results = await azureVector.query({
  indexName: 'products',
  queryVector: [0.1, 0.2, 0.3 /* ...1536 dimensions */],
  topK: 5, // Return top 5 similar results
  includeVector: false // Set to true if you want the vectors in results
});

console.log('Search results:', results);
// Output: [{ id: 'iphone-15-pro', score: 0.95, metadata: {...}, document: '...' }, ...]

Filtered Vector Search

Filters only work on fields that are present in the Azure AI Search index.

// Using structured filter syntax
const results = await azureVector.query({
  indexName: 'products',
  queryVector: [0.1, 0.2, 0.3 /* ...1536 dimensions */],
  topK: 10,
  filter: {
    and: [
      { eq: { category: 'electronics' } },
      { gt: { price: 500 } },
      { contains: { content: 'camera' } }
    ]
  }
});

Mastra Memory uses flat metadata filters for semantic recall:

const results = await azureVector.query({
  indexName: 'memory_messages',
  queryVector: [0.1, 0.2, 0.3 /* ...1536 dimensions */],
  topK: 5,
  filter: {
    resource_id: 'resource-123',
  },
});

Advanced Filtering Examples

// Complex filter with OR conditions
const complexFilter = {
  and: [
    {
      or: [
        { eq: { brand: 'Apple' } },
        { eq: { brand: 'Samsung' } }
      ]
    },
    { 
      and: [
        { ge: { price: 500 } },
        { le: { price: 1500 } }
      ]
    },
    {
      not: {
        contains: { content: 'refurbished' }
      }
    }
  ]
};

const results = await azureVector.query({
  indexName: 'products',
  queryVector: queryEmbedding,
  filter: complexFilter,
  topK: 20
});

Using Raw OData Filters

// Using raw OData filter syntax for advanced scenarios
const results = await azureVector.query({
  indexName: 'products',
  queryVector: queryEmbedding,
  filter: {
    $filter: "category eq 'electronics' and price lt 1000 and search.ismatch('smartphone', 'content')"
  },
  topK: 5
});

Advanced Features

Azure AI Search for Mastra includes the following advanced capabilities.

Semantic Search

Significantly improves result relevance using advanced language models:

// Basic semantic search
const results = await azureVector.query({
  indexName: 'my-index',
  queryVector: [0.1, 0.2 /* ...more dimensions */],
  topK: 10,
  useSemanticSearch: true,
  semanticOptions: {
    configurationName: 'my-config',
    semanticQuery: 'What is artificial intelligence?',
    answers: true,
    captions: true,
    maxWaitTime: 5000
  }
});

Multi-Vector Hybrid Search

Combines multiple vectors with different weights for more sophisticated searches:

// Multi-vector search with text vectorization
const results = await azureVector.query({
  indexName: 'my-index',
  queryVector: manualVector,
  topK: 10,
  textVectorization: {
    text: 'machine learning algorithms',
    fields: ['content_vector', 'title_vector']
  }
});

Advanced Vector Search Options

const results = await azureVector.query({
  indexName: 'my-index',
  queryVector: [0.1, 0.2 /* ...more dimensions */],
  topK: 10,
  exhaustiveSearch: true,    // Exact k-NN search for precision
  weight: 2.0,              // Relative weight in hybrid searches
  oversampling: 3,          // Only with compressed vectors
  queryType: 'full',        // 'simple' | 'full' | 'semantic'
  filterMode: 'preFilter'   // 'preFilter' | 'postFilter'
});

Document Search with Automatic Answers

const results = await azureVector.query({
  indexName: 'knowledge-base',
  queryVector: await embed('What are the benefits of AI?'),
  topK: 5,
  useSemanticSearch: true,
  semanticOptions: {
    configurationName: 'default',
    answers: true,    // Extract direct answers
    captions: true    // Generate passage summaries
  }
});

// Results will include:
// - result.metadata['@search.captions']: Automatic summaries
// - result.metadata['@search.rerankerScore']: Semantic score

Flexible Schema Support

Azure AI Search supports completely flexible schemas with customizable vector fields and advanced configurations.

Advanced Index Creation

// Create index with custom vector field and additional fields
await azureVector.createIndex({
  indexName: 'my-flexible-index',
  dimension: 512,
  vectorField: 'custom_embedding', // Custom vector field name
  additionalFields: [
    {
      name: 'title',
      type: 'Edm.String',
      searchable: true,
      filterable: true
    },
    {
      name: 'tags',
      type: 'Collection(Edm.String)',
      searchable: true,
      filterable: true,
      facetable: true
    }
  ],
  hnswParameters: {
    m: 16,              // Connections per layer
    efConstruction: 800, // Construction time accuracy
    efSearch: 500       // Query time accuracy
  },
  semanticConfig: {
    name: 'semantic-config',
    prioritizedFields: {
      titleField: { fieldName: 'title' },
      prioritizedContentFields: [{ fieldName: 'content' }],
      prioritizedKeywordsFields: [{ fieldName: 'tags' }]
    }
  }
});

Dynamic Vector Field Detection

The implementation automatically detects vector fields in existing indexes:

// Works with any existing index regardless of vector field name
const results = await azureVector.query({
  indexName: 'legacy-index', // May use 'vector', 'embedding', etc.
  queryVector: [0.1, 0.2 /* ...more dimensions */],
  topK: 5
});
// Automatically detects and uses the correct vector field

Feature Comparison

| Feature | Pinecone | Qdrant | Azure AI Search | |---------|----------|--------|---------------------| | Basic vector search | ✅ | ✅ | ✅ | | Metadata/payload filters | ✅ | ✅ | ✅ | | Hybrid lexical + vector search | ✅ | ✅ | ✅ | | Semantic reranking (platform-provided) | ❌ | ❌ | ✅ | | Automatic vectorization (platform-provided) | ✅ (integrated embedding indexes) | ❌ | ✅ (integrated vectorization) | | Exact search mode | Not explicitly exposed as query option | ✅ (exact: true) | ✅ (exhaustive: true) | | Multiple vector fields per record | Limited (single dense + single sparse index design) | ✅ (named vectors) | ✅ (multi-vector fields) | | HNSW query tuning | Not exposed as HNSW params | ✅ (hnsw_ef, collection config) | ✅ (algorithm/profile configuration) |

Comparison notes:

  • This table is based on vendor documentation and public APIs as of February 2026.
  • "Platform-provided" means available directly in the vendor platform, not via external rerankers or custom pipelines.

Updating Vectors

// Update vector and/or metadata
await azureVector.updateVector({
  indexName: 'products',
  id: 'iphone-15-pro',
  update: {
    vector: [0.2, 0.3, 0.4 /* ...more dimensions */], // New vector
    metadata: { 
      category: 'electronics',
      brand: 'Apple',
      price: 899, // Updated price
      content: 'iPhone 15 Pro Max - Now with better price!'
    }
  }
});

Managing Indexes

// List all indexes
const indexes = await azureVector.listIndexes();
console.log('Available indexes:', indexes);

// Get index information
const indexInfo = await azureVector.describeIndex({ indexName: 'products' });
console.log('Index stats:', indexInfo);
// Output: { dimension: 1536, count: 1000, metric: 'cosine' }

// Delete an index
await azureVector.deleteIndex({ indexName: 'products' });

Deleting Vectors

// Delete specific vector
await azureVector.deleteVector({
  indexName: 'products',
  id: 'iphone-15-pro'
});

Filter Syntax

Azure AI Search uses OData syntax for filtering. This package supports both structured filter objects and raw OData strings.

Structured Filter Syntax

| Operation | Description | Example | |-----------|-------------|---------| | eq | Equals | { eq: { category: 'electronics' } } | | ne | Not equals | { ne: { status: 'discontinued' } } | | gt | Greater than | { gt: { price: 100 } } | | ge | Greater than or equal | { ge: { rating: 4.0 } } | | lt | Less than | { lt: { price: 1000 } } | | le | Less than or equal | { le: { discount: 50 } } | | contains | String contains | { contains: { description: 'wireless' } } | | startsWith | String starts with | { startsWith: { name: 'iPhone' } } | | endsWith | String ends with | { endsWith: { model: 'Pro' } } | | and | Logical AND | { and: [filter1, filter2] } | | or | Logical OR | { or: [filter1, filter2] } | | not | Logical NOT | { not: filter } |

Raw OData Filter

For advanced scenarios, you can use raw OData syntax:

const filter = {
  $filter: "category eq 'electronics' and price lt 1000 and geo.distance(location, geography'POINT(-122.131577 47.678581)') le 10"
};

Error Handling

The package uses Mastra's error handling system. All errors are wrapped in MastraError objects with appropriate categorization:

import { MastraError } from '@mastra/core/error';

try {
  await azureVector.createIndex({
    indexName: 'test',
    dimension: 1536,
    metric: 'cosine'
  });
} catch (error) {
  if (error instanceof MastraError) {
    console.error('Mastra Error:', error.id);
    console.error('Details:', error.details);
  }
}

Supported Metrics

  • cosine: Cosine similarity (default, recommended for most use cases)
  • euclidean: Euclidean distance
  • dotproduct: Dot product similarity

Limitations and Considerations

Azure AI Search Limitations

  • Maximum vector dimensions: 3072 per field
  • Maximum document size: 16 MB
  • Query limits: Rate limits apply based on your pricing tier
  • Index limits: Number of indexes varies by pricing tier

Performance Considerations

  • Batch operations: Use batch upsert for better performance when inserting multiple vectors
  • Index warming: First queries might be slower on cold indexes
  • Field selection: Only select necessary fields in queries to improve performance
  • Filter optimization: Structure filters for optimal performance (equality filters first)

Best Practices

  1. Index naming: Use descriptive names following Azure naming conventions
  2. Metadata design: Keep metadata flat when possible for better filtering performance
  3. Vector dimensions: Ensure all vectors have the same dimension within an index
  4. Connection pooling: Reuse the same AzureAISearchVector instance across your application
  5. Error handling: Always wrap operations in try-catch blocks

Environment Variables

For production use, store sensitive configuration in environment variables:

# .env file
AZURE_AI_SEARCH_ENDPOINT=https://your-service.search.windows.net
AZURE_AI_SEARCH_CREDENTIAL=your-api-key
// Configuration
const azureVector = new AzureAISearchVector({
  id: 'azure-search',
  endpoint: process.env.AZURE_AI_SEARCH_ENDPOINT!,
  credential: process.env.AZURE_AI_SEARCH_CREDENTIAL!
});

TypeScript Support

This package is written in TypeScript:

import type { 
  AzureAISearchVector, 
  AzureAISearchVectorFilter,
  AzureAISearchVectorOptions 
} from 'mastra-azure-ai-search';

// Type-safe filter construction
const filter: AzureAISearchVectorFilter = {
  and: [
    { eq: { category: 'electronics' } },
    { gt: { price: 100 } }
  ]
};

Testing

This package includes tests for Azure AI Search integration with Mastra Memory.

Test Types

# Run all tests
pnpm test

# Unit tests only
pnpm test:unit

# Integration tests (requires Azure credentials)
pnpm test:integration

Memory Integration Testing

Use this package with Mastra Memory in your application-level tests:

  1. Unit Tests: Mock the vector store where your app does not need Azure behavior
  2. Scenario Tests: Add application-level tests in your Mastra app for realistic memory operations
  3. Real Integration: Validate with @mastra/memory in your application when Azure credentials are available

Running Memory Tests

# Run this package's unit tests
pnpm test:unit

# Run Azure AI Search integration tests when credentials are configured
pnpm test:integration

Memory Test Environment

For memory integration tests, set these environment variables:

# Required for all memory tests
AZURE_AI_SEARCH_ENDPOINT=https://your-service.search.windows.net
AZURE_AI_SEARCH_CREDENTIAL=your-admin-api-key

# Required for real memory integration tests
OPENAI_API_KEY=your-openai-api-key

Contributing

This package is part of the Mastra framework. For contributions:

  1. Open an issue or discussion describing the change before large refactors
  2. Ensure all tests pass: pnpm test
  3. Add tests for new functionality, especially memory-related features
  4. Test memory integration in your Mastra app when changing memory-related behavior
  5. Update documentation as needed

License

Apache-2.0.

Support