AI agents have a fundamental problem: amnesia. Every new session starts from scratch. The decisions you made yesterday, the bugs you fixed last week, the preferences you expressed a month ago โ€” all gone. I got tired of re-explaining things to my own tools.

So I built amp-mem โ€” a persistent memory system that gives AI agents the ability to remember across sessions. It's a ~500-line bash CLI backed by SQLite with FTS5 full-text search, paired with a ~490-line TypeScript plugin that hooks into Amp's event system. No vector database. No cloud service. No embeddings. Just a single SQLite file and the LLM itself as the semantic engine.

The core idea: Every session I start now has context from what I did yesterday, last week, or last month. The agent knows what decisions I've made, what tools I prefer, what workflows I've established. It captures this passively โ€” I don't have to tell it to remember. And when the volume gets too high, it distills thousands of raw observations into a handful of structured knowledge notes.

Why build it? I was running 10+ Amp sessions a day across product management, data analysis, and engineering workflows. Each session was a blank slate. I'd have to re-explain my team structure, re-state my tool preferences, re-describe ongoing projects. With 105+ skills automating my daily work, the memory problem became the biggest bottleneck โ€” not what the agent could do, but what it could remember.

The hardest challenges weren't technical โ€” they were about signal:

๐Ÿ”Š Noise at scale

The first version captured everything. After 2,718 observations, only 42 were useful โ€” a 1.5% signal rate. Seven rounds of plugin tuning cut volume by 80% while keeping the signal.

๐Ÿชž Self-referential loops

The memory system kept observing itself โ€” every amp-mem search call generated a new observation about searching memory. Meta-noise crowded out real work.

๐Ÿ”‡ Silent failures

Amp's experimental $ API for shell execution silently returned empty results. Took days to debug because the plugin appeared to work perfectly.

๐Ÿ“ Context budget

Injecting too much memory wastes the agent's context window. Too little and it forgets. Landed on a 60-line budget with sentence-boundary truncation.

How it was built: The CLI came first โ€” a bash script wrapping SQLite because I wanted zero external dependencies. Then the Amp plugin, which uses the session.start, agent.start, agent.end, and tool.result hooks to passively capture observations and inject context. AI gating (p>0.65 confidence threshold) filters low-value captures. The distillation pipeline compresses raw observations into knowledge notes, and a decay system ages out stale information over time.

I've written extensively about the journey โ€” from the initial build to tuning signal-to-noise to cutting 80% of the noise. What follows below is the technical reference.


๐Ÿ—๏ธ Architecture

~/.amp/memory/
โ”œโ”€โ”€ amp-mem.db        # SQLite database (WAL mode)
โ”œโ”€โ”€ schema.sql        # Database schema
โ””โ”€โ”€ knowledge.md      # Plain-text append-only log

~/bin/amp-mem          # CLI tool (21 subcommands)

~/.agents/skills/
โ”œโ”€โ”€ memory/SKILL.md
โ””โ”€โ”€ kb-distill/SKILL.md

๐Ÿ’ก Design Decisions

  • No vector embeddings โ€” the LLM is the semantic engine
  • SQLite + FTS5 โ€” porter stemming, single file, WAL mode
  • Progressive disclosure โ€” search โ†’ timeline โ†’ detail
  • On-demand web viewer โ€” no persistent service
  • Idempotent init โ€” safe to run every session
  • Distillation โ€” compresses observations into knowledge
  • Privacy tags โ€” <private> markers exclude from context
  • Confidence decay โ€” type-specific half-lives; permanent types never decay

๐Ÿ”Œ amp-mem Plugin

The plugin (~/.config/amp/plugins/amp-mem.ts) wraps the CLI and provides passive memory capture:

  • Passive capture โ€” automatically captures from Linear, Gmail, Slack, Notion, Google Drive, and Bash
  • Noise filtering โ€” ignores read-only tools, orchestration, and noisy ops
  • AI gating โ€” uses ctx.ai.ask() at agent.end to classify observations (p>0.65 threshold)
  • File edit batching โ€” accumulates edits per turn, saves as single observation
  • Privacy tags โ€” detects <private> and passes --private to all saves
  • Context injection โ€” injects 60-line budgeted memory at agent.start, silent (display: false), one-shot per session
  • Meta-noise filtering โ€” excludes self-referential amp-mem observations from context to avoid crowding out real work
  • Smart truncation โ€” summaries truncated at sentence boundaries (up to 400 chars) instead of hard cuts
  • Registered tools โ€” amp_mem_search, amp_mem_save, amp_mem_stats
  • Shell execution fix โ€” uses Node.js child_process.execFile instead of Amp's experimental $ tagged template (which silently fails)

โŒจ๏ธ CLI Commands

CommandDescription
initCreate/migrate database
saveSave an observation
searchFTS5 full-text search
timelineContext around an observation
detailFull observation details
contextRecent context for session priming
compactCompress old entries into summaries
session-start / endBegin or end a tracked session
statsDatabase statistics
exportExport all memory
serveWeb viewer at localhost:37777
distill-dumpDump observations for distillation
distill-recordRecord distillation run
distill-statusCheck pending observation count
decayApply confidence decay to aging observations
ingest-threadIngest an Amp thread (de-duplicated)

๐Ÿท๏ธ Observation Types

observationGeneral codebase/tool knowledge
decisionDesign decisions, trade-offs
discoveryBugs found, root causes
preferenceHow you want things done
bugfixBug fixes with context
configURLs, credentials, env details
workflowCommand sequences, processes
peopleTeam structure, ownership
sessionEnd-of-session summary

๐Ÿ”„ Distillation Pipeline

Every session, Amp checks amp-mem distill-status. If >50 pending observations or >7 days since last run, it auto-distills:

1

Gather

Dump raw observations since last distillation

2

Analyze

Cluster by topic, identify repeated patterns

3

Produce

Save distilled notes, propose AGENTS.md rules

4

Record

Mark complete โ€” rules need your approval


Installation

Get amp-mem running in under 5 minutes

๐Ÿ“ฆ Quick install: Download the CLI script and plugin from the bin/ directory on GitHub, then run the commands below.

Step 1: Download & install the CLI

# Download the CLI script
curl -fsSL https://raw.githubusercontent.com/abhiroopb/synthetic-mind/main/bin/amp-mem \
  -o ~/bin/amp-mem

# Make it executable
chmod +x ~/bin/amp-mem

# Ensure ~/bin is in your PATH (add to ~/.zshrc if not already)
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

Step 2: Install the plugin (optional โ€” enables passive capture)

# Download the Amp plugin
curl -fsSL https://raw.githubusercontent.com/abhiroopb/synthetic-mind/main/bin/amp-mem-plugin.ts \
  -o ~/.config/amp/plugins/amp-mem.ts

The plugin passively captures observations from tool usage (Linear, Gmail, Slack, etc.) and silently injects memory context once at session start (60-line budget, sentence-boundary truncation, meta-noise filtering). Uses Node.js child_process.execFile for reliable CLI execution. It's optional โ€” the CLI works standalone.

Step 3: Initialize the database

amp-mem init

This creates ~/.amp/memory/, the SQLite database, and the FTS5 search index. Safe to run multiple times (idempotent).

Step 4: Configure AGENTS.md

Add to your ~/AGENTS.md Session Start section a reference to the amp-mem plugin handling init, backup, context injection, and distill-status checks automatically.

Step 5: Verify

amp-mem init          # "Database initialized"
amp-mem stats         # 0 observations
amp-mem save observation "Test" "Testing memory"
amp-mem search "test" # Finds test observation
amp-mem serve         # Web viewer at localhost:37777

Backup & Restore

# Database backup
cp ~/.amp/memory/amp-mem.db ~/.amp/memory/amp-mem.db.bak

# Full backup
tar czf ~/amp-mem-backup.tar.gz ~/.amp/memory/ ~/bin/amp-mem

# Restore
tar xzf ~/amp-mem-backup.tar.gz -C /
amp-mem init
Full guide on GitHub โ†— Read the blog post โ†—