agent-memory-store 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD CHANGED
@@ -1,48 +1,49 @@
1
1
  # agent-memory-store
2
2
 
3
- > Local-first MCP memory server for multi-agent systems.
3
+ > High-performance MCP memory server for multi-agent systems — SQLite-backed with hybrid search.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/agent-memory-store.svg)](https://www.npmjs.com/package/agent-memory-store)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![Node.js](https://img.shields.io/badge/node-%3E%3D18-green.svg)](https://nodejs.org)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D22.5-green.svg)](https://nodejs.org)
8
8
 
9
- `agent-memory-store` gives your AI agents a shared, searchable, persistent memory — running entirely on your local filesystem. No vector database, no embedding APIs, no cloud services required.
9
+ `agent-memory-store` gives your AI agents a shared, searchable, persistent memory — powered by SQLite with native FTS5 full-text search and optional semantic embeddings. No external services required.
10
10
 
11
- Agents read and write **chunks** (markdown files with YAML frontmatter) through a set of MCP tools. Search is powered by **BM25**, the same ranking algorithm used by Elasticsearch, implemented in pure JavaScript with zero runtime dependencies.
11
+ Agents read and write **chunks** through MCP tools. Search combines **BM25 ranking** (via SQLite FTS5) with **semantic vector similarity** (via local embeddings), merged through Reciprocal Rank Fusion for best-of-both-worlds retrieval.
12
12
 
13
13
  ```
14
14
  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
15
15
  │ Agent A │ │ Agent B │ │ Agent C │
16
16
  └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
17
17
  │ │ │
18
- └────────────────┬─────────────────-┘
18
+ └────────────────┬──────────────────┘
19
19
  │ MCP tools
20
20
  ┌──────────▼──────────┐
21
- agent-memory-store │
22
- │ search · write
23
- read · state · list
21
+ agent-memory-store │
22
+ hybrid search │
23
+ BM25 + semantic
24
24
  └──────────┬──────────┘
25
25
 
26
26
  ┌──────────▼──────────┐
27
27
  │ .agent-memory-store/ │
28
- ├── chunks/
29
- │ └── state/ │
30
- └──────────────────────┘
28
+ └── store.db
29
+ └───────────────────────┘
31
30
  ```
32
31
 
33
32
  ## Features
34
33
 
35
34
  - **Zero-install usage** via `npx`
36
- - **BM25 full-text search** relevance ranking without embeddings or APIs
35
+ - **Hybrid search** — BM25 full-text (FTS5) + semantic vector similarity + Reciprocal Rank Fusion
36
+ - **SQLite-backed** — single `store.db` file, WAL mode, native performance
37
+ - **Local embeddings** — 384-dim vectors via `all-MiniLM-L6-v2`, no API keys needed
37
38
  - **Tag and agent filtering** — find chunks by who wrote them or what they cover
38
39
  - **TTL-based expiry** — chunks auto-delete after a configurable number of days
39
40
  - **Session state** — key/value store for pipeline progress, flags, and counters
40
- - **Plain files** — chunks are `.md` files, readable and editable by humans and git
41
- - **MCP-native** works with Claude Code, opencode, and any MCP-compatible client
41
+ - **MCP-native** — works with Claude Code, opencode, Cursor, and any MCP-compatible client
42
+ - **Zero external database dependencies** uses Node.js built-in SQLite (`node:sqlite`)
42
43
 
43
44
  ## Requirements
44
45
 
45
- - Node.js 18
46
+ - Node.js >= 22.5 (required for native `node:sqlite` with FTS5 support)
46
47
 
47
48
  ## Quick start
48
49
 
@@ -52,7 +53,7 @@ No installation needed:
52
53
  npx agent-memory-store
53
54
  ```
54
55
 
55
- By default, memory is stored in `.agent-memory-store/` inside the directory where the server starts — so each project gets its own isolated store automatically.
56
+ By default, memory is stored in `.agent-memory-store/store.db` inside the directory where the server starts — so each project gets its own isolated store automatically.
56
57
 
57
58
  To use a custom path:
58
59
 
@@ -60,6 +61,18 @@ To use a custom path:
60
61
  AGENT_STORE_PATH=/your/project/.agent-memory-store npx agent-memory-store
61
62
  ```
62
63
 
64
+ ## Performance
65
+
66
+ Benchmarked on Apple Silicon (Node v25, darwin arm64):
67
+
68
+ | Operation | 100 chunks | 1K chunks | 5K chunks | 10K chunks |
69
+ |-----------|-----------|-----------|-----------|------------|
70
+ | **write** | 2.16 ms | 0.15 ms | 0.15 ms | 0.15 ms |
71
+ | **read** | 0.02 ms | 0.02 ms | 0.02 ms | 0.02 ms |
72
+ | **search (BM25)** | 0.4 ms | 1.2 ms | 5.3 ms | 9.9 ms |
73
+ | **list** | 0.2 ms | 1.4 ms | 9.9 ms | 14.7 ms |
74
+ | **state get/set** | 0.03 ms | 0.03 ms | 0.03 ms | 0.03 ms |
75
+
63
76
  ## Configuration
64
77
 
65
78
  ### Claude Code
@@ -89,10 +102,12 @@ Add to your `opencode.json`:
89
102
 
90
103
  ```json
91
104
  {
105
+ "$schema": "https://opencode.ai/config.json",
92
106
  "mcp": {
93
107
  "agent-memory-store": {
94
- "command": "npx",
95
- "args": ["-y", "agent-memory-store"]
108
+ "type": "local",
109
+ "command": ["npx", "-y", "agent-memory-store"],
110
+ "enabled": true
96
111
  }
97
112
  }
98
113
  }
@@ -115,11 +130,13 @@ Add to your MCP settings file:
115
130
 
116
131
  ### Custom storage path
117
132
 
118
- If you need to store memory outside the project directory, set `AGENT_STORE_PATH` in the `env` block:
133
+ If you need to store memory outside the project directory, set `AGENT_STORE_PATH` in the environment block.
134
+
135
+ **Claude Code:**
119
136
 
120
137
  ```json
121
138
  {
122
- "mcp": {
139
+ "mcpServers": {
123
140
  "agent-memory-store": {
124
141
  "command": "npx",
125
142
  "args": ["-y", "agent-memory-store"],
@@ -131,34 +148,61 @@ If you need to store memory outside the project directory, set `AGENT_STORE_PATH
131
148
  }
132
149
  ```
133
150
 
151
+ **opencode:**
152
+
153
+ ```json
154
+ {
155
+ "$schema": "https://opencode.ai/config.json",
156
+ "mcp": {
157
+ "agent-memory-store": {
158
+ "type": "local",
159
+ "command": ["npx", "-y", "agent-memory-store"],
160
+ "enabled": true,
161
+ "environment": {
162
+ "AGENT_STORE_PATH": "/absolute/path/to/.agent-memory-store"
163
+ }
164
+ }
165
+ }
166
+ }
167
+ ```
168
+
134
169
  ### Environment variables
135
170
 
136
- | Variable | Default | Description |
137
- | ------------------ | ----------------------- | ------------------------------------------------------------------ |
171
+ | Variable | Default | Description |
172
+ |---|---|---|
138
173
  | `AGENT_STORE_PATH` | `./.agent-memory-store` | Custom path to the storage directory. Omit to use project default. |
139
174
 
140
175
  ## Tools
141
176
 
142
- | Tool | When to use |
143
- | ---------------- | ------------------------------------------------------------------------- |
177
+ | Tool | When to use |
178
+ |---|---|
144
179
  | `search_context` | **Start of every task** — retrieve relevant prior knowledge before acting |
145
- | `write_context` | After decisions, discoveries, or outputs that other agents will need |
146
- | `read_context` | Read a specific chunk by ID |
147
- | `list_context` | Inventory the memory store (metadata only, no body) |
148
- | `delete_context` | Remove outdated or incorrect chunks |
149
- | `get_state` | Read a pipeline variable (progress, flags, counters) |
150
- | `set_state` | Write a pipeline variable |
180
+ | `write_context` | After decisions, discoveries, or outputs that other agents will need |
181
+ | `read_context` | Read a specific chunk by ID |
182
+ | `list_context` | Inventory the memory store (metadata only, no body) |
183
+ | `delete_context` | Remove outdated or incorrect chunks |
184
+ | `get_state` | Read a pipeline variable (progress, flags, counters) |
185
+ | `set_state` | Write a pipeline variable |
151
186
 
152
187
  ### `search_context`
153
188
 
154
189
  ```
155
- query string Search query. Use specific, canonical terms.
156
- tags string[] (optional) Narrow to chunks matching any of these tags.
157
- agent string (optional) Narrow to chunks written by a specific agent.
158
- top_k number (optional) Max results to return. Default: 6.
159
- min_score number (optional) Minimum BM25 score. Default: 0.1.
190
+ query string Search query. Use specific, canonical terms.
191
+ tags string[] (optional) Narrow to chunks matching any of these tags.
192
+ agent string (optional) Narrow to chunks written by a specific agent.
193
+ top_k number (optional) Max results to return. Default: 6.
194
+ min_score number (optional) Minimum relevance score. Default: 0.1.
195
+ search_mode string (optional) "hybrid" (default), "bm25", or "semantic".
160
196
  ```
161
197
 
198
+ **Search modes:**
199
+
200
+ | Mode | How it works | Best for |
201
+ |---|---|---|
202
+ | `hybrid` | BM25 + semantic similarity merged via Reciprocal Rank Fusion | General use (default) |
203
+ | `bm25` | FTS5 keyword matching only | Exact term lookups, canonical tags |
204
+ | `semantic` | Vector cosine similarity only | Finding conceptually related chunks |
205
+
162
206
  ### `write_context`
163
207
 
164
208
  ```
@@ -177,33 +221,42 @@ key string State variable name.
177
221
  value any (set_state only) Any JSON-serializable value.
178
222
  ```
179
223
 
180
- ## Storage format
224
+ ## Architecture
181
225
 
182
- Each chunk is a plain `.md` file under `.agent-memory-store/chunks/`:
183
-
184
- ```markdown
185
- ---
186
- id: a3f9c12b40
187
- topic: "Auth service — chose JWT over sessions"
188
- agent: architect-agent
189
- tags: [auth, architecture, decision]
190
- importance: high
191
- updated: 2025-06-01T14:32:00.000Z
192
- ---
193
-
194
- Chose stateless JWT over server-side sessions.
195
-
196
- **Rationale:** No shared session store needed across services.
197
- Refresh tokens stored in Redis with 7-day TTL.
198
- Access tokens expire in 15 minutes.
199
-
200
- **Trade-offs:** Cannot invalidate individual tokens before expiry.
201
- Acceptable for our threat model.
202
226
  ```
227
+ src/
228
+ index.js MCP server — tool registration and transport
229
+ store.js Public API — searchChunks, writeChunk, readChunk, etc.
230
+ db.js SQLite layer — node:sqlite with FTS5, WAL mode
231
+ search.js Hybrid search — FTS5 BM25 + vector similarity + RRF
232
+ embeddings.js Local embeddings — @huggingface/transformers (all-MiniLM-L6-v2)
233
+ bm25.js Pure JS BM25 — kept as fallback reference
234
+ migrate.js Filesystem → SQLite migration (automatic, one-time)
235
+ ```
236
+
237
+ ### Storage format
238
+
239
+ All data lives in a single SQLite database at `.agent-memory-store/store.db`:
240
+
241
+ - **chunks table** — id, topic, agent, tags (JSON), importance, content, embedding (BLOB), timestamps, expiry
242
+ - **chunks_fts** — FTS5 virtual table synced via triggers for full-text search
243
+ - **state table** — key/value pairs for pipeline variables
244
+
245
+ WAL mode is enabled for concurrent read performance. No manual flush needed.
246
+
247
+ ### How hybrid search works
248
+
249
+ 1. **BM25 (FTS5)** — SQLite's native full-text search ranks chunks by term frequency and inverse document frequency. Fast, deterministic, great for exact keyword matches.
203
250
 
204
- Session state lives in `.agent-memory-store/state/<key>.json`.
251
+ 2. **Semantic similarity** Query and chunks are embedded into 384-dimensional vectors using `all-MiniLM-L6-v2` (runs locally via ONNX Runtime). Cosine similarity finds conceptually related chunks even when exact terms don't match.
205
252
 
206
- Both directories are human-readable, diffable with git, and can be committed to version control if you want shared team memory.
253
+ 3. **Reciprocal Rank Fusion** — Both ranked lists are merged using RRF with weights (BM25: 0.4, semantic: 0.6). Documents appearing in both lists get boosted.
254
+
255
+ The embedding model (~23MB) is downloaded automatically on first use and cached in `~/.cache/huggingface/`. If the model fails to load, the system falls back to BM25-only search transparently.
256
+
257
+ ### Migration from filesystem
258
+
259
+ If you're upgrading from a previous version that used `.md` files, the migration happens automatically on first startup. Your existing chunks and state are imported into SQLite, and the old directories are renamed to `chunks_backup/` and `state_backup/`.
207
260
 
208
261
  ## Agent system prompt
209
262
 
@@ -216,8 +269,8 @@ You have access to a persistent local memory store via agent-memory-store MCP to
216
269
 
217
270
  **At the start of each task:**
218
271
 
219
- 1. Call `search_context` with 23 specific queries related to what you are about to do.
220
- 2. Incorporate retrieved chunks (score > 1.0) into your reasoning.
272
+ 1. Call `search_context` with 2-3 specific queries related to what you are about to do.
273
+ 2. Incorporate retrieved chunks into your reasoning.
221
274
  3. Call `get_state` to check pipeline status if relevant.
222
275
 
223
276
  **After completing a subtask:**
@@ -232,33 +285,13 @@ You have access to a persistent local memory store via agent-memory-store MCP to
232
285
  **Best practices:**
233
286
 
234
287
  - Specific topics: "ZAP scraper — stack decision" > "decision"
235
- - Consistent tags: always use the same term (`auth`, not `authentication` or `autenticação`)
288
+ - Consistent tags: always use the same term (`auth`, not `authentication`)
236
289
  - Check before writing: search first to avoid duplicate chunks
237
290
  - Temporary context: use `ttl_days: 7` for session-scoped information
291
+ - Use `search_mode: "semantic"` when looking for conceptually related chunks
292
+ - Use `search_mode: "bm25"` for exact tag/keyword lookups
238
293
  ```
239
294
 
240
- ## How BM25 search works
241
-
242
- BM25 ranks documents by term frequency and inverse document frequency, normalized by document length. It is the ranking algorithm behind Elasticsearch and Apache Lucene.
243
-
244
- **Strengths:**
245
-
246
- - Works well for short, labeled text chunks
247
- - Instant — no network calls, no GPU, no warm-up
248
- - Deterministic and explainable
249
-
250
- **Limitations:**
251
-
252
- - No semantic understanding (`car` ≠ `automobile`)
253
- - Mitigated by using canonical tags and consistent terminology across agents
254
-
255
- **Score interpretation:**
256
-
257
- - `> 3.0` — strong match, highly relevant
258
- - `1.0 – 3.0` — good match, likely relevant
259
- - `0.1 – 1.0` — weak match, may be tangentially related
260
- - `< 0.1` — filtered out by default
261
-
262
295
  ## Development
263
296
 
264
297
  ```bash
@@ -274,22 +307,20 @@ Run tests:
274
307
  npm test
275
308
  ```
276
309
 
277
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
278
-
279
- ## Project structure
310
+ Run benchmark:
280
311
 
312
+ ```bash
313
+ node benchmark.js
281
314
  ```
282
- src/
283
- bm25.js BM25 ranking engine — pure JS, zero dependencies
284
- store.js File-based persistence (chunks + session state)
285
- index.js MCP server and tool definitions
286
- ```
315
+
316
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
287
317
 
288
318
  ## Roadmap
289
319
 
290
320
  - [ ] `summarize_context` tool — LLM-powered chunk consolidation
291
321
  - [ ] `prune_context` tool — remove chunks by age, agent, or importance
292
- - [ ] Hybrid scoring: BM25 + optional local embedding reranking (ollama)
322
+ - [x] ~~Hybrid scoring: BM25 + local embedding reranking~~ — shipped in v0.1.0
323
+ - [x] ~~SQLite-backed storage~~ — shipped in v0.1.0
293
324
  - [ ] Web UI for browsing the memory store
294
325
  - [ ] Multi-project workspace support
295
326
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-memory-store",
3
- "version": "0.0.4",
4
- "description": "Local-first MCP memory server for multi-agent systems. BM25 search, zero external dependencies, file-based persistence.",
3
+ "version": "0.0.6",
4
+ "description": "Local-first MCP memory server for multi-agent systems. Hybrid search (BM25 + semantic embeddings), SQLite-backed, zero-config.",
5
5
  "type": "module",
6
6
  "exports": "./src/index.js",
7
7
  "bin": {
@@ -10,7 +10,7 @@
10
10
  "scripts": {
11
11
  "start": "node src/index.js",
12
12
  "test": "node --test src/__tests__/store.test.js",
13
- "lint": "node --check src/bm25.js src/store.js src/index.js"
13
+ "lint": "node --check src/bm25.js src/store.js src/index.js src/db.js src/embeddings.js src/search.js src/migrate.js"
14
14
  },
15
15
  "keywords": [
16
16
  "mcp",
@@ -20,6 +20,11 @@
20
20
  "memory",
21
21
  "rag",
22
22
  "bm25",
23
+ "embeddings",
24
+ "semantic-search",
25
+ "sqlite",
26
+ "vector",
27
+ "kv-store",
23
28
  "context",
24
29
  "opencode",
25
30
  "claude",
@@ -36,7 +41,7 @@
36
41
  },
37
42
  "homepage": "https://github.com/vbfs/agent-memory-store#readme",
38
43
  "engines": {
39
- "node": ">=18.0.0"
44
+ "node": ">=22.5.0"
40
45
  },
41
46
  "files": [
42
47
  "src/",
@@ -44,6 +49,7 @@
44
49
  "LICENSE"
45
50
  ],
46
51
  "dependencies": {
52
+ "@huggingface/transformers": "^3.0.0",
47
53
  "@modelcontextprotocol/sdk": "^1.28.0",
48
54
  "gray-matter": "^4.0.3",
49
55
  "zod": "^4.3.6"