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 zodTool 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 },
});