Verified by the sovseal team

Mastra Agent Memory Integration

Build autonomous Node.js/TypeScript agents with Mastra using the local-first, zero-knowledge sovseal memory adapter.

Integrate Mastra with sovseal to build highly stateful TypeScript agents that persist customer details, previous tool decisions, and workflow logs across runs.

Mastra exposes a lightweight createTool API. Wrapping the @sovseal/sdk client in Mastra tools allows models to dynamically invoke store_memory and recall_memory during execution.

Installation

Install the Mastra core and @sovseal/sdk dependencies:

npm install @mastra/core @sovseal/sdk @ai-sdk/openai zod

Tool Definitions

Create your tool files wrapping the AgentStateClient API:

  • File Path: src/agent/tools.ts
import { createTool } from "@mastra/core/tools";
import { AgentStateClient } from "@sovseal/sdk";
import { z } from "zod";

// Initialize the client
const client = new AgentStateClient({
  endpoint: "https://ksrlmubaxzwufziwarps.supabase.co/functions/v1/v2-agent-state",
  apiKey: process.env.SOVSEAL_API_KEY || "",
});

// Import key for AES client-side encryption
const getCryptoKey = async () => {
  const rawKey = Buffer.from(process.env.SOVSEAL_ENCRYPTION_KEY || "", "base64");
  return crypto.subtle.importKey(
    "raw",
    rawKey,
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  );
};

export const recallMemoryTool = createTool({
  id: "sovseal-recall",
  description: "Search the local vector store for user preferences, previous decisions, and system history.",
  inputSchema: z.object({
    userId: z.string().describe("The user ID to look up memories for."),
    query: z.string().describe("The search query to match against memories."),
  }),
  outputSchema: z.object({
    context: z.string().describe("The recalled memory string."),
  }),
  execute: async ({ context }) => {
    try {
      const { receipt } = await client.restore({ agentId: context.userId });
      return {
        context: receipt.active_context?.content || "No memories found.",
      };
    } catch (err) {
      return { context: `Recall failed: ${(err as Error).message}` };
    }
  },
});

export const storeMemoryTool = createTool({
  id: "sovseal-store",
  description: "Store a new preference, convention, or fact in the user's persistent memory.",
  inputSchema: z.object({
    userId: z.string().describe("The user ID to store memories for."),
    fact: z.string().describe("The declarative fact to save."),
  }),
  execute: async ({ context }) => {
    const key = await getCryptoKey();
    
    // Retrieve current memory first to append
    let currentMemory = "";
    try {
      const { receipt } = await client.restore({ agentId: context.userId });
      currentMemory = receipt.active_context?.content || "";
    } catch {}

    await client.snapshot({
      key,
      payload: {
        agent_id: context.userId,
        sequence_number: Date.now(),
        parent_snapshot: null,
        policy_hash: "0".repeat(64),
        active_context: { content: `${currentMemory}\n- ${context.fact}`.trim() },
        timestamp: new Date().toISOString(),
      },
    });

    return { success: true };
  },
});

Agent Setup

Wire the memory tools into your Mastra agent definition:

  • File Path: src/agent/index.ts
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { recallMemoryTool, storeMemoryTool } from "./tools";

export const memoryAgent = new Agent({
  name: "SovereignAssistant",
  instructions: `
    You are a personalized AI helper.
    Always call the 'sovseal-recall' tool first on starting a chat to search for user context.
    Use the 'sovseal-store' tool whenever the user volunteers useful personal preferences or workflow guidelines.
  `,
  model: openai("gpt-4o"),
  tools: { recallMemoryTool, storeMemoryTool },
});

On this page