memory_save
Store facts, decisions, preferences, or lessons in long-term memory with automatic embedding for semantic retrieval.
Instructions
Save a fact, decision, preference, or lesson to long-term memory. Automatically generates an embedding for future semantic search.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | The memory content — be specific and self-contained | |
| category | No | Memory category (default: general) | |
| project | No | Associated project name |
Implementation Reference
- The handler function that executes the memory_save tool logic. It generates an ID, embeds the content via Ollama, inserts a row into the SQLite memories table, and returns a confirmation string.
export async function handleMemorySave( content: string, category: MemoryCategory = "general", project?: string, ): Promise<string> { const db = getDb(); const now = Date.now(); const id = generateId("mem"); const embedding = await embed(content); const embeddingBuf = embedding ? embeddingToBuffer(embedding) : null; db.prepare( `INSERT INTO memories (id, content, category, project, created_at, updated_at, accessed_at, embedding) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, ).run(id, content, category, project ?? null, now, now, now, embeddingBuf); const projectStr = project ? ` [${project}]` : ""; return `Saved memory ${id}${projectStr} (${category}):\n${content.slice(0, 100)}${content.length > 100 ? "..." : ""}`; } - Type definition for MemoryCategory, used as input schema for the handler function.
export type MemoryCategory = | "decision" | "preference" | "fact" | "episode" | "lesson" | "architecture" | "framework" | "general"; - packages/server/src/index.ts:247-269 (registration)Registration of the memory_save tool with the MCP server, including Zod schema for content, category, and project inputs.
server.tool( "memory_save", "Save a fact, decision, preference, or lesson to long-term memory. Automatically generates an embedding for future semantic search.", { content: z.string().describe("The memory content — be specific and self-contained"), category: z .enum(["decision", "preference", "fact", "episode", "lesson", "architecture", "framework", "general"]) .optional() .describe("Memory category (default: general)"), project: z.string().optional().describe("Associated project name"), }, async ({ content, category, project }) => { try { const result = await handleMemorySave(content, category, project); return { content: [{ type: "text", text: result }] }; } catch (err) { return { content: [{ type: "text", text: `Error saving memory: ${err}` }], isError: true, }; } }, ); - Helper function that generates unique IDs with a prefix (used as 'mem-...' for memory entries).
export function generateId(prefix: string): string { const ts = Date.now(); const rand = Math.random().toString(36).slice(2, 6); return `${prefix}-${ts}-${rand}`; } - Helper that generates an embedding vector for memory content using Ollama's nomic-embed-text model.
export async function embed(text: string): Promise<Float32Array | null> { const available = await ensureOllama(); if (!available) return null; const client = getClient(); const response = await client.embed({ model: MODEL, input: text }); return new Float32Array(response.embeddings[0]); }