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 +123 -92
- package/package.json +10 -4
- package/src/db.js +354 -0
- package/src/embeddings.js +124 -0
- package/src/index.js +21 -8
- package/src/migrate.js +124 -0
- package/src/search.js +151 -0
- package/src/store.js +112 -185
package/README.MD
CHANGED
|
@@ -1,48 +1,49 @@
|
|
|
1
1
|
# agent-memory-store
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> High-performance MCP memory server for multi-agent systems — SQLite-backed with hybrid search.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/agent-memory-store)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
[](https://nodejs.org)
|
|
8
8
|
|
|
9
|
-
`agent-memory-store` gives your AI agents a shared, searchable, persistent memory —
|
|
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**
|
|
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
|
-
│
|
|
22
|
-
│ search
|
|
23
|
-
│
|
|
21
|
+
│ agent-memory-store │
|
|
22
|
+
│ hybrid search │
|
|
23
|
+
│ BM25 + semantic │
|
|
24
24
|
└──────────┬──────────┘
|
|
25
25
|
│
|
|
26
26
|
┌──────────▼──────────┐
|
|
27
27
|
│ .agent-memory-store/ │
|
|
28
|
-
│
|
|
29
|
-
|
|
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
|
|
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
|
-
- **
|
|
41
|
-
- **
|
|
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
|
|
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
|
|
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
|
-
"
|
|
95
|
-
"
|
|
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
|
|
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
|
-
"
|
|
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
|
|
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
|
|
143
|
-
|
|
177
|
+
| Tool | When to use |
|
|
178
|
+
|---|---|
|
|
144
179
|
| `search_context` | **Start of every task** — retrieve relevant prior knowledge before acting |
|
|
145
|
-
| `write_context`
|
|
146
|
-
| `read_context`
|
|
147
|
-
| `list_context`
|
|
148
|
-
| `delete_context` | Remove outdated or incorrect chunks
|
|
149
|
-
| `get_state`
|
|
150
|
-
| `set_state`
|
|
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
|
|
156
|
-
tags
|
|
157
|
-
agent
|
|
158
|
-
top_k
|
|
159
|
-
min_score
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
|
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 2
|
|
220
|
-
2. Incorporate retrieved chunks
|
|
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`
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
## Project structure
|
|
310
|
+
Run benchmark:
|
|
280
311
|
|
|
312
|
+
```bash
|
|
313
|
+
node benchmark.js
|
|
281
314
|
```
|
|
282
|
-
|
|
283
|
-
|
|
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
|
-
- [
|
|
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
|
-
"description": "Local-first MCP memory server for multi-agent systems.
|
|
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": ">=
|
|
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"
|