Skip to main content

Overview

Save significant work, decisions, discoveries, and learnings to persistent memory. Call this proactively after completing important tasks — don’t wait to be asked.
This is a core tool in the agent profile, always loaded in the MCP context.

When to Save

Call mem_save after each of these:
  • Architectural decisions or tradeoffs — chose JWT over sessions, microservices vs monolith
  • Bug fixes — what was wrong, why it happened, how you fixed it
  • New patterns or conventions — established a naming convention, file structure
  • Configuration changes — environment setup, build config, CI/CD changes
  • Important discoveries or gotchas — API behavior, edge cases, performance findings
  • File structure changes — created new directories, reorganized modules

Parameters

title
string
required
Short, searchable titleExamples:
  • “JWT auth middleware”
  • “Fixed N+1 query in user list”
  • “FTS5 query sanitization”
  • “Switched to TypeScript strict mode”
Keep it concise (under 80 characters) and focused on the what, not the why.
content
string
required
Structured content using the What/Why/Where/Learned formatUse this exact structure:
**What**: [concise description of what was done]
**Why**: [the reasoning, user request, or problem that drove it]
**Where**: [files/paths affected, e.g. src/auth/middleware.ts]
**Learned**: [gotchas, edge cases, or decisions — omit if none]
Focus on:
  • What was changed (concise, high-level)
  • Why it was needed (the problem or goal)
  • Where the changes are (file paths, line numbers)
  • What you learned (non-obvious insights, gotchas)
Don’t include:
  • Full code diffs (the git repo has that)
  • Step-by-step instructions (focus on outcomes)
  • Obvious implementation details
type
string
Category for the observationRecognized types:
  • decision — architectural or technical decisions
  • architecture — system design, structure, patterns
  • bugfix — bug fixes and incident resolutions
  • pattern — conventions, guidelines, code patterns
  • config — configuration, setup, environment changes
  • discovery — technical findings, investigations
  • learning — lessons learned, gotchas
  • manual (default) — general observations
The type affects:
  • Search filtering (users can filter by type)
  • Topic key generation (used for upserts)
  • Categorization in the TUI
session_id
string
Session ID to associate with this observationDefault: manual-save-{project} or manual-save if no projectLinks the observation to a coding session for timeline context.
project
string
Project nameAssociates the observation with a specific project for filtering and scoping.Example: my-api, engram, frontend
scope
string
Visibility scope for this observationOptions:
  • project (default) — visible only within this project
  • personal — cross-project, personal knowledge
Use personal for:
  • Language-specific patterns (e.g., “Go error handling pattern”)
  • Tool usage tips (e.g., “Git rebase vs merge”)
  • General learnings that apply across projects
Use project (default) for:
  • Project-specific decisions
  • Architecture choices
  • Bug fixes tied to this codebase
topic_key
string
Optional topic identifier for upsertsFormat: family/segment (e.g., architecture/auth-model, bug/fts5-sanitization)When to use:
  • Evolving architectural decisions that should update a single observation
  • Ongoing bug investigations that refine over time
  • Living documentation that gets revised
How it works:
  • If an observation with the same topic_key, project, and scope exists, it’s updated (revision count increments)
  • If not, a new observation is created
Get a stable topic key: Use mem_suggest_topic_key to generate a normalized key:
{
  "type": "architecture",
  "title": "Database schema design"
}
// Returns: "architecture/database-schema-design"

Response

result
string
Confirmation message with the saved observation details
Example responses:
Memory saved: "JWT auth middleware" (decision)
Memory saved: "Fixed N+1 query" (bugfix)
Suggested topic_key: bug/n1-query-user-list

Usage Examples

Bug Fix

{
  "title": "Fixed FTS5 syntax error on special chars",
  "type": "bugfix",
  "content": "**What**: Wrapped each search term in quotes before passing to FTS5 MATCH\n**Why**: Users typing queries like 'fix auth bug' would crash because FTS5 interprets special chars as operators\n**Where**: internal/store/store.go — sanitizeFTS() function\n**Learned**: FTS5 MATCH syntax is NOT the same as LIKE — always sanitize user input",
  "project": "engram"
}

Architectural Decision

{
  "title": "Switched from sessions to JWT",
  "type": "decision",
  "content": "**What**: Replaced express-session with jsonwebtoken for auth\n**Why**: Session storage doesn't scale across multiple instances\n**Where**: src/middleware/auth.ts, src/routes/login.ts\n**Learned**: Must set httpOnly and secure flags on the cookie, refresh tokens need separate rotation logic",
  "project": "my-api",
  "scope": "project"
}

Pattern with Topic Key

{
  "title": "Go error handling pattern",
  "type": "pattern",
  "content": "**What**: Established consistent error wrapping with fmt.Errorf and %w\n**Why**: Makes error traces debuggable without stack traces\n**Where**: All internal/* packages\n**Learned**: Use %w for wrapping, %v for formatting — errors.Is() requires %w",
  "scope": "personal",
  "topic_key": "pattern/go-error-handling"
}

Discovery

{
  "title": "SQLite WAL mode performance",
  "type": "discovery",
  "content": "**What**: Enabled WAL mode with PRAGMA journal_mode=WAL\n**Why**: Default DELETE mode causes lock contention on concurrent reads\n**Where**: internal/store/store.go line 299\n**Learned**: WAL allows simultaneous reads+writes but creates -wal and -shm files. Safe to delete only when DB is closed.",
  "project": "engram"
}

Structured Format

Always use the What/Why/Where/Learned format in the content field:
Concise description of what was doneFocus on the outcome, not the steps:
  • ✅ “Added JWT authentication to API endpoints”
  • ✅ “Refactored UserService to use repository pattern”
  • ❌ “First I created a new file, then I imported jwt, then…”
The reasoning, problem, or user request that drove itExplain the motivation:
  • ✅ “Session cookies don’t scale across multiple server instances”
  • ✅ “User requested ability to export data as CSV”
  • ❌ “Because it’s better” (too vague)
Files and paths affectedBe specific:
  • src/auth/middleware.ts (line 45)
  • internal/store/store.go, internal/mcp/mcp.go
  • ❌ “The auth files” (too vague)
  • ❌ Full file paths with absolute directories (use relative paths from project root)
Gotchas, edge cases, non-obvious insightsCapture the surprises:
  • ✅ “FTS5 requires quotes around search terms with special chars”
  • ✅ “Must close WAL files before SQLite backup”
  • ❌ “It works now” (no insight)
Omit if there are no notable learnings — not every save needs a Learned section.

Deduplication

Engram automatically detects duplicate observations:
  • Duplicate detection window: 15 minutes (configurable)
  • Matching criteria: Same session + same content hash
  • Behavior: Updates duplicate_count instead of creating a new entry
If you call mem_save twice with identical content within 15 minutes, the duplicate count increments but only one observation is stored.

Topic Key Upserts

When topic_key is provided:
  1. Engram searches for an existing observation with:
    • Same topic_key
    • Same project
    • Same scope
  2. If found:
    • Content is replaced with new content
    • revision_count increments
    • updated_at timestamp refreshes
  3. If not found:
    • New observation is created
Use topic keys for evolving knowledge — architecture decisions, ongoing investigations, living documentation.

When NOT to Save

  • Raw tool calls — don’t save every edit, bash, or read action
  • Trivial changes — typo fixes, formatting, minor refactors
  • Work in progress — save when a task is complete, not mid-implementation
  • Duplicate context — if you already saved it, don’t save again (unless using topic_key for updates)
The agent decides what’s worth remembering. Only save high-signal observations — not a firehose of raw activity.

Build docs developers (and LLMs) love