Llm Memory Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Llm Memory Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A local-first, team-ready MCP server that provides a durable memory system for LLM-based coding workflows. It's optimized for JavaScript/TypeScript development (web and mobile), but works for any stack. Memory items can be stored globally, locally per project, or committed to the repo for team sharing — with fast search, ranking, and per-scope tuning.
Prerequisites:
npm install -g pnpm)git clone <repository-url>
cd llm-memory-mcp
pnpm install
pnpm run buildFor optimal storage efficiency with 50-100x compression, you can optionally install FFmpeg and configure video storage:
macOS:
# Using Homebrew
brew install ffmpeg
# Using MacPorts
sudo port install ffmpegLinux (Ubuntu/Debian):
# Ubuntu/Debian
sudo apt update
sudo apt install ffmpeg
# Fedora/RHEL
sudo dnf install ffmpeg
# Arch Linux
sudo pacman -S ffmpegWindows:
# Using Chocolatey
choco install ffmpeg
# Using Scoop
scoop install ffmpegThe system defaults to file (JSON) storage for maximum compatibility. To use video storage, explicitly configure it via config.json with "storage": { "backend": "video" } or set the LLM_MEMORY_DEFAULT_BACKEND=video environment variable.
1) Start the server
pnpm start2) Configure in your MCP client
llm-memorynode["/absolute/path/to/llm-memory-mcp/dist/index.js"]llm-memorynode/absolute/path/to/llm-memory-mcp/dist/index.jscodex config set mcp.servers.llm-mem.command "node"
codex config set mcp.servers.llm-mem.args "['/absolute/path/to/llm-memory-mcp/dist/index.js']"This repository includes a specialized agent (agents/dev-memory-manager.md) designed for intelligent development knowledge curation with Claude Code. The agent automatically captures critical context before conversation compacting, preserves development progress across sessions, and maintains a living knowledge base.
The dev-memory-manager agent provides:
# On macOS/Linux
cp agents/dev-memory-manager.md ~/.claude/agents/
# On Windows
copy agents\dev-memory-manager.md %USERPROFILE%\.claude\agents\The agent activates automatically when you:
Manual activation examples:
# Preserve context before conversation compacting
Use the dev-memory-manager agent to save our authentication implementation progress
# Retrieve previous session context
Use the dev-memory-manager agent to get our payment integration context from yesterday
# Capture a complete solution
Use the dev-memory-manager agent to store this debugging journey and solutionContext Preservation (Priority)
Knowledge Types Captured
session: Work-in-progress and conversation statesnippet: Reusable code blocks with clear utilitypattern: Architectural designs and best practicesinsight: Lessons learned and gotchasrunbook: Step-by-step proceduresjourney: Complete problem-solving narrativesSmart Storage Strategy
Pre-Compacting Preservation:
Long conversation about implementing OAuth → Context limit approaching → Agent automatically saves:
- Current implementation state
- Testing approach and results
- Next planned steps
- Links to related documentationSession Continuity:
New conversation → "Continue payment integration work" → Agent retrieves:
- Previous session progress
- Code state and file modifications
- Current blockers and decisions made
- Relevant patterns and insightsKnowledge Evolution:
Debugging session → Solution found → Agent captures:
- Complete problem description
- All attempted solutions
- Final working solution with explanation
- Links to related issues and patternswip, blocked, next-sessionThe agent respects your LLM Memory MCP server configuration:
No additional configuration needed - the agent adapts to your existing memory setup.
Automatically capture development knowledge from your git commits to build a searchable knowledge base of your coding patterns, solutions, and insights.
1. Tag commits with `#kb` to capture knowledge:
git commit -m "Implement JWT authentication with refresh tokens #kb #security"2. System automatically captures:
3. Process captured events:
{ "name": "autolearn.processQueue", "arguments": {} }4. Knowledge becomes searchable:
{
"name": "memory.query",
"arguments": {
"q": "JWT authentication",
"scope": "project",
"k": 10
}
}The auto-learning system consists of three integrated components:
1. Git Hooks (automatically installed)
commit-msg: Detects #kb tags in commit messagespost-commit: Captures commit details to queue file2. Event Queue (.llm-memory/autolearn-queue.ndjson)
3. Materialization (converts events to memories)
Check System Status:
{ "name": "autolearn.status", "arguments": {} }Returns:
Initialize Auto-Learning:
{ "name": "autolearn.init", "arguments": { "autoInstall": true } }Installs git hooks and Claude Code hooks/agents.
Process Event Queue:
{ "name": "autolearn.processQueue", "arguments": {} }Processes all queued events and creates memories.
Capture Specific Commit:
{ "name": "autolearn.captureCommit", "arguments": { "commitHash": "HEAD" } }Manually capture a commit (useful for retroactive capture).
Install Globally:
{ "name": "autolearn.installGlobally", "arguments": {} }Install hooks and agents in your global Claude Code directory (~/.claude/).
Capture Bug Fix:
git commit -m "Fix race condition in authentication middleware #kb #bug #async"Creates an insight memory with:
Capture Pattern:
git commit -m "Refactor API client with retry logic pattern #kb #pattern #resilience"Creates a pattern memory documenting the retry pattern.
Capture Configuration:
git commit -m "Add ESLint config for TypeScript strict mode #kb #config #typescript"Creates a config memory with the configuration template.
When you connect the MCP server to Claude Code (or other MCP clients), the system automatically:
#kb in commitsNo manual setup required! The system works out of the box.
The dev-memory-manager agent integrates with auto-learning to:
#kb tags to important commitsThis creates a seamless workflow where you focus on coding and committing, and the system automatically builds your knowledge base.
Auto-learning respects the standard memory configuration system. Configure via project.config.set:
{
"name": "project.config.set",
"arguments": {
"scope": "local",
"config": {
"version": "1",
"autolearn": {
"enabled": true,
"captureTypes": ["commit", "fix", "refactor", "pattern"],
"gitHooks": {
"enabled": true,
"tagPattern": "#kb",
"captureDiffs": true,
"maxDiffSize": 10000
},
"filters": {
"minLinesChanged": 5,
"includePatterns": ["**/*.ts", "**/*.js"],
"excludePatterns": ["**/node_modules/**", "**/dist/**"]
},
"storage": {
"scope": "local",
"defaultType": "snippet"
}
}
}
}
}When to Use `#kb` Tags:
When NOT to Use `#kb` Tags:
Tagging Strategy:
# Include descriptive context tags
git commit -m "Add rate limiting middleware #kb #security #express #middleware"
# Use type indicators
git commit -m "Fix memory leak in WebSocket handler #kb #bug #websocket"
# Reference related systems
git commit -m "Refactor authentication flow #kb #pattern #auth #jwt"Hooks not triggering?
# Check hook installation
ls -la .git/hooks/ | grep -E '(commit-msg|post-commit)'
# Verify executable permissions
chmod +x .git/hooks/commit-msg .git/hooks/post-commit
# Check for marker file (created after #kb commit)
ls -la .git/llm-memory-autolearn.tmpQueue not processing?
# Check queue contents
cat .llm-memory/autolearn-queue.ndjson
# Check system status
echo '{"name":"autolearn.status","arguments":{}}' | node dist/index.js
# Manually process queue
echo '{"name":"autolearn.processQueue","arguments":{}}' | node dist/index.jsAgents not active?
# Check agent installation
ls -la ~/.claude/agents/ | grep dev-memory-manager
# Check project-level agents
ls -la .claude/agents/
# Restart Claude Code to reload agentsFor more detailed documentation, see docs/AUTO_LEARNING.md.
The LLM Memory MCP Server supports three storage backends, each optimized for different use cases:
Perfect for: Knowledge management, team wikis, Obsidian users, human-readable storage
Stores memories as individual markdown files with YAML frontmatter, fully compatible with Obsidian and other markdown tools. Each memory is a standalone .md file with:
[[memory-id-title]])Benefits:
Storage Structure:
_LLM_memories/
react-project/ # Project-based subfolder (from repoId)
01ABC-react-hooks.md
01DEF-typescript-patterns.md
nodejs-api/ # Different project
01GHI-express-middleware.md
_global/ # Memories without specific project
01JKL-git-workflow.mdMemories are automatically organized by project using the repoId from their context. This makes it easy to:
Perfect for: Large codebases, storage-constrained environments, archival
Revolutionary video-based storage system that achieves 50-100x compression ratios while maintaining sub-100ms search performance. Uses QR code encoding combined with video compression to dramatically reduce storage requirements.
Content → QR Code Encoding → Video Frame → H.264/H.265 Compression → Ultra-Compact Storage
1KB → 2.4x comp → Frame → 50-80x total → ~20 bytesKey Technologies:
Storage Efficiency by Content Type:
┌────────────────┬──────────────┬──────────────┬──────────────┐
│ Content Type │ Original │ Video (H264) │ Video (H265) │
├────────────────┼──────────────┼──────────────┼──────────────┤
│ Code Snippets │ 1x │ 47x │ 62x │
│ Documentation │ 1x │ 53x │ 71x │
│ JSON Config │ 1x │ 78x │ 94x │
│ Mixed Content │ 1x │ 51x │ 68x │
│ Average │ 1x │ 57x │ 74x │
└────────────────┴──────────────┴──────────────┴──────────────┘Perfect for: Maximum compatibility, no dependencies, debugging
Traditional JSON-based storage with optimized journaling and content-based hashing. Each memory is stored as a separate JSON file with automatic journal compaction.
Benefits:
Storage Structure:
items/
01ABC.json
01DEF.json
journal-optimized.ndjson
catalog.jsonThe system uses file (JSON) storage by default and detects existing storage formats:
Detection Priority:
storage.backend setting in config.json_LLM_memories/ directory with .md filessegments/ directory with video filesLLM_MEMORY_DEFAULT_BACKEND settingExplicit Backend Configuration:
// config.json - explicitly set your preferred backend
{
"storage": {
"backend": "file" // or "video" or "markdown"
}
}Environment Variable:
# Set default backend via environment
export LLM_MEMORY_DEFAULT_BACKEND=video # or "file" or "markdown"Search Performance (1M memory items):
┌────────────────┬─────────┬─────────┬─────────┬──────────┐
│ Operation │ P50 │ P95 │ P99 │ Max │
├────────────────┼─────────┼─────────┼─────────┼──────────┤
│ Video Decode │ 8ms │ 19ms │ 31ms │ 58ms │
│ Hybrid Search │ 23ms │ 54ms │ 86ms │ 167ms │
│ Context Pack │ 45ms │ 98ms │ 156ms │ 298ms │
└────────────────┴─────────┴─────────┴─────────┴──────────┘Cache Performance:
Automatic Configuration: The system automatically selects the optimal storage backend and configures compression settings. No manual configuration required.
Manual Configuration (Advanced):
{
"storage": {
"backend": "video",
"videoOptions": {
"codec": "h264",
"crf": 26,
"preset": "medium",
"errorCorrection": "M"
}
}
}Configuration Options:
backend: "auto" (default), "file", "video", "markdown"codec: "h264" (default), "h265" (video only)crf: Quality setting (18-28, lower = higher quality) (video only)preset: Encoding speed ("fast", "medium", "slow") (video only)errorCorrection: QR error correction ("L", "M", "Q", "H") (video only)The system provides seamless migration between all three storage backends (file ↔ video ↔ markdown):
Check Migration Status:
{ "name": "mig.status", "arguments": { "scope": "local", "backend": "video" } }Migrate to Video Storage:
{ "name": "mig.storage.backend", "arguments": {
"sourceBackend": "file",
"targetBackend": "video",
"scope": "local",
"validateAfterMigration": true
}}Migration Features:
FFmpeg Not Found:
# Verify FFmpeg installation
ffmpeg -version
# Check PATH configuration
which ffmpeg
# Test video encoding capability
echo '{"name": "maint.verify", "arguments": {"scope": "local"}}' | node dist/index.jsPerformance Issues:
Storage Issues:
# Check storage backend status
echo '{"name": "mig.status", "arguments": {"scope": "local"}}' | node dist/index.js
# Validate video storage integrity
echo '{"name": "mig.validate", "arguments": {"scope": "local", "backend": "video"}}' | node dist/index.js
# Get detailed storage metrics
echo '{"name": "maint.verify", "arguments": {"scope": "all"}}' | node dist/index.jsDebug Mode:
# Enable debug logging
DEBUG="llm-memory:video" pnpm start
# Test with specific backend
LLM_MEMORY_FORCE_BACKEND=file pnpm start
LLM_MEMORY_FORCE_BACKEND=video pnpm start~/.llm-memory/global)~/.llm-memory/projects/<repoId>)<project>/.llm-memory)File Storage Layout (Traditional):
<scope-root>/
items/ # one JSON per MemoryItem
index/
inverted.json # inverted index
lengths.json # document lengths
meta.json # index metadata
catalog.json # id -> MemoryItemSummary
jour.ndjson # legacy append-only change log (auto-migrated)
journal-optimized.ndjson # optimized journal with SHA-256 hashes (95% smaller)
locks/ # advisory lock files
tmp/ # atomic write staging
config.json # per-scope configurationVideo Storage Layout (Compressed):
<scope-root>/
segments/
consolidated.mp4 # video file containing QR-encoded content
consolidated-index.json # frame-to-content mapping
index/
inverted.json # BM25 search index
vec.bin # vector embeddings (optional)
meta.json # index metadata
catalog.json # id -> MemoryItemSummary with frame references
tmp/ # atomic write staging
config.json # per-scope configuration (includes storage backend)
snapshot-meta.json # integrity verification metadataMarkdown Storage Layout:
<scope-root>/
_LLM_memories/ # Root memories folder
project-a/ # Project-specific subfolders (based on repoId)
01ABC-component.md
01DEF-util.md
project-b/
01GHI-api.md
_global/ # Memories without specific project
01JKL-pattern.md
.memory/ # Hidden metadata directory
catalog.json # id → MemoryItemSummary
config.json # per-scope configuration
index/ # Search indexes
inverted.json
vectors.bin
meta.jsonStorage Backend Auto-Selection:
config.json contains storage.backend field indicating active backendInitialize committed scope in current project:
{ "name": "proj.initCommitted", "arguments": {} }When using markdown storage backend, memories are fully compatible with Obsidian, enabling powerful knowledge management features:
{ "name": "project.config.set", "arguments": {
"scope": "local",
"config": { "version": "1", "storage": { "backend": "markdown" } }
}}~/.llm-memory/global/_LLM_memories/~/.llm-memory/projects/<project-hash>/_LLM_memories/<project>/.llm-memory/_LLM_memories/Project Organization: Memories are automatically organized into subfolders based on their project (repoId):
_LLM_memories/react-app/ - Memories from your React project_LLM_memories/api-server/ - Memories from your API project_LLM_memories/_global/ - Memories without a specific project[[memory-id-title]] to navigateEach memory is a markdown file with YAML frontmatter:
---
id: 01JDF97ZMB000000000000001
type: pattern
scope: global
title: React Hooks Best Practices
language: typescript
tags: [react, hooks, best-practices]
confidence: 0.85
pinned: false
createdAt: 2025-10-11T13:10:00.000Z
updatedAt: 2025-10-11T13:10:00.000Z
version: 1
---
# React Hooks Best Practices
Essential patterns for using React Hooks effectively.
## Code
\`\`\`typescript
// Your code here
\`\`\`
## Related Memories
- [[01ABC-typescript-generics]]
- [[01DEF-react-performance]]
## Context
- **Tool**: Claude Code
- **Framework**: ReactFor programmatic access to your Obsidian vault, install the Local REST API plugin:
This enables powerful workflows like:
.llm-memory in repoconfig.json for a scopeconfig.json for a scopeResources
Key fields (see src/types/Memory.ts):
The quality.confidence field (0-1) is automatically calculated using:
Confidence scores directly influence search ranking, with higher confidence items receiving boost multipliers.
Recommended usage for JS/TS projects:
type: 'snippet', set language: 'typescript' or 'javascript'.files and symbols for better retrieval.pattern for recurring designs; config for templates; insight/fact for distilled learnings.Create a snippet (local scope):
{
"name": "mem.upsert",
"arguments": {
"type": "snippet",
"scope": "local",
"title": "React Error Boundary",
"language": "typescript",
"code": "class ErrorBoundary extends React.Component { /* ... */ }",
"tags": ["react", "error-handling"],
"files": ["src/components/ErrorBoundary.tsx"],
"symbols": ["ErrorBoundary"]
}
}Query snippets/patterns for React:
{
"name": "mem.query",
"arguments": {
"q": "react",
"scope": "project",
"k": 10,
"filters": { "type": ["snippet", "pattern"] }
}
}Pin an important pattern:
{ "name": "mem.pin", "arguments": { "id": "01H..." } }Link related items:
{ "name": "mem.link", "arguments": { "from": "01A...", "to": "01B...", "rel": "refines" } }Record positive feedback for confidence scoring:
{ "name": "mem.feedback", "arguments": { "id": "01H...", "helpful": true, "scope": "local" } }Record usage event for confidence scoring:
{ "name": "mem.use", "arguments": { "id": "01H...", "scope": "local" } }Check storage backend and migration status:
{ "name": "mig.status", "arguments": { "scope": "local", "backend": "video" } }Migrate from file to markdown storage (Obsidian-compatible):
{ "name": "migration.storage.backend", "arguments": {
"sourceBackend": "file",
"targetBackend": "markdown",
"scope": "local",
"validateAfterMigration": true
}}Migrate from file to video storage (ultra-compressed):
{ "name": "mig.storage.backend", "arguments": {
"sourceBackend": "file",
"targetBackend": "video",
"scope": "local",
"validateAfterMigration": true
}}Migrate from markdown to video storage:
{ "name": "mig.validate", "arguments": { "scope": "local", "backend": "video" } }Rebuild catalog and index for project scopes:
{ "name": "maint.rebuild", "arguments": { "scope": "project" } }Claude can now proactively check for relevant memories before starting tasks:
// Claude invokes the check-memory prompt
{
"name": "check-memory",
"arguments": {
"task": "Implement JWT token rotation",
"files": "src/auth/jwt.ts, src/middleware/auth.ts",
"context": "feature/auth-improvements"
}
}Returns formatted markdown with relevant memories, code snippets, and confidence scores to help Claude discover existing knowledge patterns automatically.
mem.context)Inspired by how Claude's memory system works, memories can now be marked for automatic injection into prompts, with token-budget-aware retrieval.
Injection Policy:
Memories can have an injection field with two values:
Create an always-inject memory:
{ "name": "mem.upsert", "arguments": {
"type": "fact",
"scope": "local",
"injection": "always",
"title": "User Preferences",
"text": "User prefers TypeScript over JavaScript. Always use strict mode.",
"tags": ["preferences", "typescript"]
}}Retrieve memories for prompt injection:
{ "name": "mem.context", "arguments": {
"scope": "project",
"maxTokens": 4000,
"minConfidence": 0.5
}}Parameters:
scope - Which scopes to search (global, local, committed, project, all)maxTokens - Token budget for output (default: 4000)includeAlwaysInject - Include all 'always' injection memories first (default: true)format - Output format: json or markdown (default: json)minConfidence - Minimum confidence threshold (default: 0.5)types - Filter by memory types (e.g., ["fact", "insight"])tags - Filter by tagsOutput Formats:
JSON Format (default) - Machine-readable:
{
"memories": [
{
"id": "01ABC...",
"type": "fact",
"injection": "always",
"confidence": 0.95,
"title": "User Preferences",
"content": "User prefers TypeScript over JavaScript",
"tags": []
}
]
}Markdown Format - Human-readable documentation:
# Memories
## User Preferences
**Type:** fact | **Confidence:** 95% | **Injection:** always
User prefers TypeScript over JavaScriptHow it works:
injection='always' items are included first (they get priority)This mirrors Claude's architecture where "user memories" are always injected, while "conversation history" is retrieved on-demand.
mem.recent)Retrieve recently accessed or modified memories, sorted by recency. This is useful for reviewing recent work or continuing where you left off.
Get 10 most recently accessed memories:
{ "name": "mem.recent", "arguments": {
"scope": "project",
"limit": 10
}}Get memories modified in the last 24 hours:
{ "name": "mem.recent", "arguments": {
"scope": "local",
"sortBy": "updatedAt",
"since": "2024-01-14T00:00:00Z"
}}Parameters:
scope - Which scopes to search (global, local, committed, project, all)limit - Maximum number of results (default: 10)types - Filter by memory types (e.g., ["snippet", "insight"])tags - Filter by tagssortBy - Sort field: lastUsedAt, lastAccessedAt, updatedAt, or createdAt (default: lastAccessedAt)since - Only return items accessed/modified since this ISO dateEdit memories without full rewrites, inspired by Claude's str_replace and insert commands:
Fix a typo:
{ "name": "mem.patch", "arguments": {
"id": "01HX...",
"operations": [
{ "field": "text", "old": "authetication", "new": "authentication" }
]
}}Add new learnings:
{ "name": "mem.append", "arguments": {
"id": "01HX...",
"field": "text",
"content": "Update: Also works with OAuth2 flows",
"separator": "\n\n"
}}Combine duplicate memories:
{ "name": "mem.merge", "arguments": {
"sourceIds": ["01HX...", "01HY...", "01HZ..."],
"scope": "local",
"strategy": "deduplicate",
"deleteSource": true
}}Merge strategies:
concat — Simple concatenationdeduplicate — Remove duplicate lines (default)prioritize-first — Keep first item's contentprioritize-recent — Use most recently updated contentVideo Storage Compatibility: All incremental operations work seamlessly with video storage through a read-modify-write pattern. The system reads the item (decodes frame), modifies it in memory, then writes back via upsert (creates new frame). Old frames are preserved for history/recovery.
Automatically manage memory lifecycle with time-to-live settings:
Create temporary memory:
{ "name": "mem.upsert", "arguments": {
"type": "insight",
"scope": "local",
"text": "Debugging auth flow - using test token ABC123",
"quality": { "ttlDays": 7 }
}}Preview expired memories:
{ "name": "maint.prune", "arguments": {
"scope": "local",
"dryRun": true
}}Remove expired memories:
{ "name": "maint.prune", "arguments": {
"scope": "local",
"dryRun": false
}}Extend TTL for valuable memories:
{ "name": "mem.renew", "arguments": {
"id": "01HX...",
"ttlDays": 90
}}Common TTL patterns:
Video Storage: Pruning removes catalog entries while preserving video frames for potential recovery.
Search uses BM25 with configurable boosts. Tune per scope via config.json and proj.config.*.
Config (subset):
interface MemoryConfig {
version: string;
ranking?: {
fieldWeights?: { title?: number; text?: number; code?: number; tag?: number };
bm25?: { k1?: number; b?: number };
scopeBonus?: { global?: number; local?: number; committed?: number };
pinBonus?: number;
recency?: { halfLifeDays?: number; scale?: number };
phrase?: { bonus?: number; exactTitleBonus?: number };
hybrid?: { enabled?: boolean; wBM25?: number; wVec?: number; model?: string };
};
contextPack?: {
order?: Array<'snippets'|'facts'|'patterns'|'configs'>;
caps?: { snippets?: number; facts?: number; patterns?: number; configs?: number };
};
maintenance?: {
compactEvery?: number; // compact after N journal appends (default: 500)
compactIntervalMs?: number; // time-based compaction (default: 24h)
snapshotIntervalMs?: number; // time-based snapshot (default: 24h)
indexFlush?: { maxOps?: number; maxMs?: number }; // index scheduler flush thresholds
};
}Recommended defaults (JS/TS):
Set committed-scope tuning:
{
"name": "proj.config.set",
"arguments": {
"scope": "committed",
"config": {
"version": "1",
"ranking": {
"fieldWeights": { "title": 6, "text": 2, "code": 1.2, "tag": 3 },
"bm25": { "k1": 1.4, "b": 0.7 },
"scopeBonus": { "committed": 2.0, "local": 1.0, "global": 0.3 },
"pinBonus": 3,
"recency": { "halfLifeDays": 7, "scale": 2.5 },
"phrase": { "bonus": 3, "exactTitleBonus": 8 },
"hybrid": { "enabled": true, "wBM25": 0.7, "wVec": 0.3, "model": "local-emb" }
}
}
}
}After changing field weights, run maint.rebuild for the affected scope to re-apply indexing weights.
The confidence scoring algorithm can be tuned via the confidence section in config.json:
interface ConfidenceConfig {
// Bayesian prior for helpfulness (Laplace smoothing)
priorAlpha?: number; // default: 1
priorBeta?: number; // default: 1
basePrior?: number; // default: 0.5
// Time-based decay
usageHalfLifeDays?: number; // default: 14
recencyHalfLifeDays?: number; // default: 7
// Usage saturation
usageSaturationK?: number; // default: 5
// Weights for linear blend
weights?: {
feedback?: number; // default: 0.35
usage?: number; // default: 0.25
recency?: number; // default: 0.20
context?: number; // default: 0.15
base?: number; // default: 0.05
};
// Pinned behavior
pin?: {
floor?: number; // default: 0.8
multiplier?: number; // default: 1.05
};
}Example configuration:
{
"name": "proj.config.set",
"arguments": {
"scope": "committed",
"config": {
"version": "1",
"confidence": {
"usageHalfLifeDays": 21,
"recencyHalfLifeDays": 10,
"weights": {
"feedback": 0.4,
"usage": 0.3,
"recency": 0.2,
"context": 0.1
}
}
}
}
}The system includes local embedding generation using transformers.js and HNSW vector indexing for high-performance semantic search. This enables:
Three pre-configured models, all running locally via transformers.js:
| Model | Dimensions | Max Tokens | Best For | Speed |
|---|---|---|---|---|
| bge-small-en-v1.5 (default) | 384 | 512 | Code and technical documentation | ⚡⚡ |
| all-MiniLM-L6-v2 | 384 | 256 | General text, fast inference | ⚡⚡⚡ |
| all-mpnet-base-v2 | 768 | 384 | Higher quality semantic matching | ⚡⚡ |
First run downloads the model (~25-90MB depending on model), then cached locally in .cache/transformers/.
1. Enable embeddings in configuration:
{ "name": "proj.config.set", "arguments": { "scope": "committed", "config": { "version": "1", "ranking": { "hybrid": { "enabled": true, "wBM25": 0.7, "wVec": 0.3, "model": "local-emb" } } } } }2. Create a memory (auto-embedding happens in background):
{ "name": "vec.set", "arguments": { "scope": "local", "id": "01ABC...", "vector": [0.1, -0.2, 0.05, ...] } }3. Manually embed specific memories:
{ "name": "mem.query", "arguments": { "q": "authentication flow", "scope": "project", "k": 20, "vector": [/* query embedding */], "filters": { "type": ["snippet", "pattern"] } } }4. Batch embed multiple memories:
{ "name": "vec.importJsonl", "arguments": { "scope": "local", "path": "/abs/path/vec.jsonl", "dim": 768 } }5. Generate embedding for raw text:
{ "name": "vec.importBulk", "arguments": { "scope": "local", "items": [{"id":"01A","vector":[0.1,0.2]},{"id":"01B","vector":[0.0,0.3]}] } }Build an IDE-ready pack of code snippets, facts, configs, and patterns, tuned for JS/TS:
mem.contextPackkb://context/packExample:
{ "name": "mem.contextPack", "arguments": { "q": "react hooks", "scope": "project", "k": 12, "tokenBudget": 2000, "snippetLanguages": ["typescript","tsx"], "snippetFilePatterns": ["src/**/*.ts","src/**/*.tsx"] } }URI form:
kb://context/pack?q=react%20hooks&scope=project&k=12&tokenBudget=2000&snippetLanguages=typescript,tsx&snippetFilePatterns=src/**/*.ts,src/**/*.tsxPer-scope order/caps are configurable in config.json under contextPack.
maint.compactEvery (default 500). Triggers compaction after N journal appends.maint.compactIntervalMs (default 24h).maint.replay — replay journal; optional compactmaint.compact — compact scope(s)maint.compact.now — immediate compactionmaint.compactSnapshot — compaction + snapshot in one stepmaint.snapshot — write snapshot meta (for fast tail replay)maint.verify — recompute checksum and compare to snapshot/state-okState-ok markers
index/state-ok.json containing the last verified checksum and timestamp.maint.verify reports whether current checksum matches both snapshot and state-ok markers.On upsert, common credential patterns are redacted from text/code and hashed into security.secretHashRefs to prevent leakage into committed mem.
pnpm install
pnpm run dev
pnpm run build
pnpm run typecheck
pnpm run lint
pnpm run test:all # end-to-end tool tests
pnpm run simulate:user # simulated JS/TS flowLLM_MEMORY_HOME_DIR="$(pwd)" LLM_MEMORY_SKIP_STARTUP_REPLAY=1 pnpm run test:allLLM_MEMORY_HOME_DIR="$(pwd)" LLM_MEMORY_SKIP_STARTUP_REPLAY=1 pnpm run simulate:userLLM_MEMORY_STARTUP_REPLAY_MS=2000 pnpm run test:alldim override to vec.importBulk / vec.importJsonl, orrm -f .llm-memory/index/vec.json .llm-memory/index/vec.meta.jsonmaint.compactSnapshot (project/all), then maint.verify should report ok=true.state-ok marker.rm -f to ignore missing files, or enable NULL_GLOB temporarily: setopt NULL_GLOB."type": "module" to package.json or run Node with --input-type=module to silence the warning.Manual test:
node test-memory-tools.js — exercises mem.* tools via stdio{ "name": "mem.upsert", "arguments": {
"type": "pattern",
"scope": "committed",
"title": "React Error Boundary",
"language": "typescript",
"text": "Wrap subtree with an error boundary component; log and render fallback UI.",
"code": "class ErrorBoundary extends React.Component { /* ... */ }",
"tags": ["react","error-handling","ts"],
"files": ["src/components/ErrorBoundary.tsx"],
"symbols": ["ErrorBoundary"]
} }{ "name": "mem.query", "arguments": {
"scope": "project",
"k": 20,
"filters": { "tags": ["react"] }
} }{ "name": "mem.contextPack", "arguments": {
"q": "debounce util",
"scope": "project",
"k": 12,
"tokenBudget": 1800,
"snippetLanguages": ["typescript","tsx"],
"snippetFilePatterns": ["src/utils/**/*.ts","src/utils/**/*.tsx"]
} }{ "name": "mem.pin", "arguments": { "id": "01H..." } }{ "name": "proj.sync.status", "arguments": {} }{ "name": "proj.sync.merge", "arguments": {} }{ "name": "proj.config.set", "arguments": {
"scope": "committed",
"config": { "version": "1", "sharing": { "enabled": true, "sensitivity": "team" } }
} }{ "name": "proj.config.set", "arguments": {
"scope": "local",
"config": { "version": "1", "ranking": { "hybrid": { "enabled": true, "wBM25": 0.7, "wVec": 0.3 } } }
} }{ "name": "vec.set", "arguments": { "scope": "local", "id": "01ABC...", "vector": [0.1, -0.2, 0.05] } }{ "name": "mem.query", "arguments": { "q": "auth flow", "scope": "project", "k": 20, "vector": [0.08, -0.15, 0.02] } }{ "name": "maint.compact.now", "arguments": { "scope": "project" } }{ "name": "maint.compactSnapshot", "arguments": { "scope": "all" } }{ "name": "maint.verify", "arguments": { "scope": "project" } }The system automatically uses an optimized journal format that reduces storage by 81-95% through content-based hashing:
{ "name": "jour.stats", "arguments": { "scope": "all" } }{ "name": "jour.migrate", "arguments": { "scope": "project" } }{ "name": "jour.verify", "arguments": { "scope": "local" } }The confidence scoring system automatically learns from your usage patterns and feedback to improve search relevance over time:
Example workflow:
// Create a useful code snippet
{ "name": "mem.upsert", "arguments": {
"type": "snippet",
"scope": "local",
"title": "React useDebounce Hook",
"code": "const useDebounce = (value, delay) => { /* implementation */ }",
"language": "typescript",
"tags": ["react", "hooks", "performance"]
}}
// Record usage when you actually use it
{ "name": "mem.use", "arguments": { "id": "01ABC...", "scope": "local" } }
// Provide feedback when it proves helpful
{ "name": "mem.feedback", "arguments": { "id": "01ABC...", "helpful": true, "scope": "local" } }
// Search will now rank this item higher in future queries
{ "name": "mem.query", "arguments": { "q": "react debounce", "scope": "project", "k": 10 } }~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.