Skip to content
SilasReinagelPublic

About

CLI memory system for AI agents. SQLite + FTS5. Hot/warm/cold event tiers, entities, lessons, principles.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

agentmem

CLI memory system for AI agents. Built on SQLite with FTS5 full-text search.

Features

  • Multi-agent support — Each agent has isolated memory via --user
  • Event tiers — Automatic hot/warm/cold classification based on age
  • Full-text search — FTS5-powered search across events, entities, and lessons
  • Session bootstrap — Single command returns all context needed to start a session
  • Zero dependencies — Uses Bun's native SQLite, no npm packages required

Installation

Requires Bun v1.0+.

# Clone and use directly
git clone https://github.com/SilasReinagel/agentmem.git
cd agentmem
bun index.js session --user=myagent

# Or install globally
bun install -g agentmem
agentmem session --user=myagent

Quick Start

# Start a session (compact text — token-efficient for agent bootstrap)
agentmem session --user=myagent

# Full JSON output (backward compatible, for scripts)
agentmem session --user=myagent --format=json

# Store an event
agentmem store --user=myagent --type=event '{"type":"work_session","title":"Built feature X","content":"Implemented the new dashboard..."}'

# Store a lesson learned
agentmem store --user=myagent --type=lesson '{"type":"observation","title":"Always test edge cases","content":"Found a bug because..."}'

# Search memories
agentmem search --user=myagent --query="dashboard"

# Get/set agent state
agentmem state --user=myagent "## Current Focus\nWorking on dashboard"
agentmem state --user=myagent

Commands

session

Get everything needed to start a session in one call.

# Default: compact text (best for agent bootstrap)
agentmem session --user=myagent

# JSON: full structured output (for scripts or debugging)
agentmem session --user=myagent --format=json

Default output (compact) — scannable text sections:

=STATE (Jul06)=
## Current Focus
...

=EVENTS (12)=
Jul09 10:51 | work_session | Task: Built feature X
Jul09 10:37 | finding | Done in workspace 1...

=PRINCIPLES (4)=
- optimize-for-context-switches: Silas works in rapid context-switching mode...

=LESSONS (10)=
Jul06 | observation | PR 24883 builtin catalog...

JSON output (--format=json) returns the same data as structured objects with full metadata.

Session filtering (signal-only bootstrap):

  • Hot events allowlist: work_session, finding, decision only
  • Noisy types (tool_result, tool_call, etc.) are excluded — use recall or search to find those
  • Events with identical (normalized) titles within 24 hours are deduplicated (keeps most recent)
  • Manual/curated events preferred over memsyncd auto-ingest (source_path / Task: titles) when capping
  • State older than 24h (or empty) shows ! STALE STATE in compact output; JSON includes state.stale / state.age_hours

Returns:

  • Current state (with stale flag)
  • Hot events (last 72 hours, max 15 after filter/dedupe)
  • All principles
  • Most recent summary
  • Recent unconsolidated lessons (max 10)

state

Get or set the agent's current state (scratchpad).

# Get state
agentmem state --user=myagent

# Set state
agentmem state --user=myagent "## Focus\nBuilding memory system"

store

Store new memories. Supports: event, entity, lesson, principle, summary.

# Store event
agentmem store --user=myagent --type=event '{"type":"work_session","title":"Title","content":"Details..."}'

# Store entity (project, person, tool, etc.)
agentmem store --user=myagent --type=entity '{"type":"project","name":"myproject","content":"Description..."}'

# Store lesson
agentmem store --user=myagent --type=lesson '{"type":"feedback","title":"Lesson title","content":"What was learned..."}'

# Store principle (consolidated from lessons)
agentmem store --user=myagent --type=principle '{"name":"principle-name","content":"The principle...","source_lessons":["lesson-id-1"]}'

# Pipe from stdin
echo '{"type":"work_session","title":"Test","content":"..."}' | agentmem store --user=myagent --type=event

recall

Recall memories with filters.

# Get hot events
agentmem recall --user=myagent --type=events --filters='{"tier":"hot"}'

# Get events by type
agentmem recall --user=myagent --type=events --filters='{"event_type":"decision"}'

# Get events since date
agentmem recall --user=myagent --type=events --filters='{"since":"2026-01-01T00:00:00Z"}'

# Get entities by type
agentmem recall --user=myagent --type=entities --filters='{"entity_type":"project"}'

# Get all principles
agentmem recall --user=myagent --type=principles

search

Full-text search across memories.

# Search all types
agentmem search --user=myagent --query="authentication"

# Search specific types
agentmem search --user=myagent --query="authentication" --types=events,lessons

# Limit results
agentmem search --user=myagent --query="authentication" --limit=5

export

Export memories to markdown files.

# Export all
agentmem export --user=myagent --target=./backup

# Export specific types
agentmem export --user=myagent --target=./backup --types=events,lessons

# Export since date
agentmem export --user=myagent --target=./backup --since=2026-01-01T00:00:00Z

Data Model

Events

Time-based memories with automatic tier classification:

  • hot — Last 72 hours
  • warm — 72 hours to 30 days
  • cold — Older than 30 days
{
  "type": "work_session|decision|discovery|error|...",
  "title": "Short description",
  "content": "Full details",
  "metadata": { "tags": ["optional"] }
}

Entities

Reference information about projects, people, tools, etc.

{
  "type": "project|person|tool|concept|...",
  "name": "unique-name",
  "content": "Description and details"
}

Lessons

Learnings that can be consolidated into principles.

{
  "type": "feedback|success|failure|observation",
  "title": "What was learned",
  "content": "Details and context",
  "source_event_id": "optional-event-reference"
}

Principles

Consolidated wisdom from multiple lessons.

{
  "name": "principle-name",
  "content": "The distilled principle",
  "source_lessons": ["lesson-1", "lesson-2"]
}

Agent Integration

The CLI handles storage and retrieval. Semantic operations (summarization, consolidation) belong in the calling agent. Here are the patterns:

Weekly Summary

Compress a week's events into a narrative summary.

# 1. Recall events for the period
agentmem recall --user=myagent --type=events \
  --filters='{"since":"2026-01-20T00:00:00Z","until":"2026-01-27T00:00:00Z"}' \
  --limit=100

# 2. Agent synthesizes summary using LLM (your responsibility)
# Input: the events JSON
# Output: narrative summary + event count

# 3. Store the summary
agentmem store --user=myagent --type=summary '{
  "type": "week",
  "period": "2026-W04",
  "content": "## Week 4 Summary\n\nFocused on authentication system...",
  "event_count": 23
}'

Lesson → Principle Consolidation

When patterns emerge across multiple lessons, consolidate into a principle.

# 1. Recall unconsolidated lessons
agentmem recall --user=myagent --type=lessons --limit=50
# Filter for consolidated_to: null in the results

# 2. Agent identifies patterns and synthesizes principle (your responsibility)
# Input: lessons with similar themes
# Output: distilled principle

# 3. Store the principle with source references
agentmem store --user=myagent --type=principle '{
  "name": "infrastructure-over-discipline",
  "content": "When a behavior must happen reliably, encode it in infrastructure (automation, constraints, defaults) rather than relying on human discipline. Discipline fails under stress; infrastructure persists.",
  "source_lessons": ["2026-01-15-003", "2026-01-18-007", "2026-01-22-001"]
}'

# 4. Mark source lessons as consolidated (update each)
agentmem store --user=myagent --type=lesson '{
  "id": "2026-01-15-003",
  "type": "observation",
  "title": "Original title",
  "content": "Original content",
  "consolidated_to": "myagent/infrastructure-over-discipline"
}'

Session Lifecycle

Recommended flow for an agent session:

# 1. Session start: get all context in one call (compact text by default)
agentmem session --user=myagent
# Returns: state, hot_events, principles, recent_summary, recent_lessons
# Use --format=json if a script needs structured output

# 2. During session: store events as they happen
agentmem store --user=myagent --type=event '{"type":"work_session",...}'

# 3. End of session: update state, store lessons learned
agentmem state --user=myagent "## Current Focus\nUpdated focus..."
agentmem store --user=myagent --type=lesson '{"type":"observation",...}'

# 4. Periodic maintenance (weekly): run summary consolidation
# See "Weekly Summary" pattern above

Tier Management

Event tiers update automatically when you call store. The thresholds:

  • hot: < 72 hours old
  • warm: 72 hours to 30 days
  • cold: > 30 days

No manual intervention needed. Query by tier using:

agentmem recall --user=myagent --type=events --filters='{"tier":"hot"}'
agentmem recall --user=myagent --type=events --filters='{"tier":"warm"}' --limit=50

Configuration

Environment Variable Description Default
AGENTMEM_DB_PATH Custom database path ~/.agentmem/memory.db
AGENTMEM_HOST Sidecar bind address 127.0.0.1
AGENTMEM_PORT Sidecar port 8422

Sidecar

agentmem serve is an HTTP and MCP process in front of the same SQLite file. The CLI keeps working. The id you pass as --user is the project id on the API.

A key authorizes one or more projects. The request selects the project. * allows every project and still requires the caller to name one.

agentmem key create --label=cursor --projects=one-percent-club
agentmem serve

The create command prints the key once. Send it as Authorization: Bearer am_....

curl -s http://127.0.0.1:8422/health

curl -s -X POST http://127.0.0.1:8422/v1/projects/one-percent-club/store \
  -H "Authorization: Bearer $AGENTMEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"event","data":{"type":"decision","title":"Use sqlite","content":"Shared with the CLI"}}'

curl -s -X POST http://127.0.0.1:8422/v1/projects/one-percent-club/search \
  -H "Authorization: Bearer $AGENTMEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"sqlite"}'
Method Path Body
GET /health Open. No key.
GET /v1/projects/:project/session?format=json format=compact returns text. Default is JSON.
GET /v1/projects/:project/state
PUT /v1/projects/:project/state { "content": "..." }
POST /v1/projects/:project/store { "type": "event", "data": { ... } }
POST /v1/projects/:project/recall { "type": "events", "filters": {}, "limit": 20 }
POST /v1/projects/:project/search { "query": "...", "types": ["events"] }
POST /mcp MCP streamable HTTP. Tools: session, get_state, set_state, store, recall, search.

Claude and Cursor attach to http://127.0.0.1:8422/mcp with the bearer key. If the key allows one project, tools can omit project. Otherwise pass project or the X-Project header.

The process binds to localhost. On a Droplet, publish it through TLS. Do not put the raw port on the public internet.

docker build -t agentmem .
docker run -d --name agentmem \
  -p 127.0.0.1:8422:8422 \
  -v agentmem-data:/data \
  agentmem
docker exec agentmem bun index.js key create --label=cursor --projects=one-percent-club

Development

# Run tests
bun test

# Run tests in watch mode
bun test --watch

# Run with coverage
bun test --coverage

Architecture

  • Database: SQLite with WAL mode and FTS5 indexes
  • Location: ~/.agentmem/memory.db by default
  • Runtime: Bun (uses native bun:sqlite)

License

MIT

About

CLI memory system for AI agents. SQLite + FTS5. Hot/warm/cold event tiers, entities, lessons, principles.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages