@jcyamacho/agent-memory 0.0.8 → 0.0.9
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 +31 -50
- package/dist/index.js +29 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,23 +60,12 @@ With a custom database path:
|
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Optional LLM instructions to reinforce the MCP's built-in guidance:
|
|
64
64
|
|
|
65
65
|
```text
|
|
66
|
-
Use `
|
|
67
|
-
or
|
|
68
|
-
|
|
69
|
-
Use `memory_remember` only for durable context worth reusing later:
|
|
70
|
-
preferences, conventions, decisions, constraints, and stable workflow habits.
|
|
71
|
-
Store one concise fact per memory, include `workspace` when relevant, and avoid
|
|
72
|
-
secrets or temporary notes.
|
|
73
|
-
|
|
74
|
-
For `memory_recall`, pass 2-5 short, distinctive `terms` as separate array
|
|
75
|
-
items. Prefer project names, file names, APIs, feature names, issue IDs, and
|
|
76
|
-
brief phrases. Avoid one long sentence.
|
|
77
|
-
|
|
78
|
-
Use `workspace` to bias results toward the current project. Use `created_*`
|
|
79
|
-
only when time range matters.
|
|
66
|
+
Use `recall` at the start of every conversation. Use `remember` when the user
|
|
67
|
+
corrects your approach, a key decision is established, or you learn project
|
|
68
|
+
context not obvious from the code.
|
|
80
69
|
```
|
|
81
70
|
|
|
82
71
|
## What It Stores
|
|
@@ -130,25 +119,31 @@ Inputs:
|
|
|
130
119
|
memory content; avoid full natural-language questions
|
|
131
120
|
- `limit` -> maximum results to return
|
|
132
121
|
- `workspace` -> workspace or repo path; biases ranking toward this workspace
|
|
133
|
-
- `
|
|
134
|
-
- `
|
|
122
|
+
- `updated_after` -> ISO 8601 lower bound
|
|
123
|
+
- `updated_before` -> ISO 8601 upper bound
|
|
135
124
|
|
|
136
125
|
Output:
|
|
137
126
|
|
|
138
127
|
- `results[]` with `id`, `content`, `score`, `workspace`, and `updated_at`
|
|
139
128
|
|
|
140
|
-
##
|
|
141
|
-
|
|
142
|
-
For normal usage:
|
|
129
|
+
## How Ranking Works
|
|
143
130
|
|
|
144
|
-
-
|
|
131
|
+
`recall` uses a multi-signal ranking system to surface the most relevant
|
|
132
|
+
memories:
|
|
145
133
|
|
|
146
|
-
|
|
134
|
+
1. **Text relevance** is the primary signal -- memories whose content best
|
|
135
|
+
matches your search terms rank highest.
|
|
136
|
+
2. **Workspace match** is a strong secondary signal. When you pass `workspace`,
|
|
137
|
+
memories saved with the same workspace rank above unrelated ones.
|
|
138
|
+
3. **Global memories** (saved without a workspace) are treated as relevant
|
|
139
|
+
everywhere. They rank between workspace-matching and non-matching memories.
|
|
140
|
+
4. **Recency** is a minor tiebreaker -- newer memories rank slightly above older
|
|
141
|
+
ones when other signals are equal.
|
|
147
142
|
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
For best results, always pass `workspace` when calling `recall`. Save memories
|
|
144
|
+
without a workspace only when they apply across all projects.
|
|
150
145
|
|
|
151
|
-
|
|
146
|
+
## Database location
|
|
152
147
|
|
|
153
148
|
By default, the SQLite database is created at:
|
|
154
149
|
|
|
@@ -171,9 +166,17 @@ Set `AGENT_MEMORY_DB_PATH` when you want to:
|
|
|
171
166
|
Beta note: schema changes are not migrated. If you are upgrading from an older
|
|
172
167
|
beta, delete the existing memory DB and let the server create a new one.
|
|
173
168
|
|
|
174
|
-
##
|
|
169
|
+
## Development
|
|
170
|
+
|
|
171
|
+
For working on the project itself or running from source. Requires Bun and
|
|
172
|
+
Node.js.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bun install
|
|
176
|
+
bun run build
|
|
177
|
+
```
|
|
175
178
|
|
|
176
|
-
|
|
179
|
+
To use a local build as your MCP server:
|
|
177
180
|
|
|
178
181
|
```json
|
|
179
182
|
{
|
|
@@ -182,39 +185,17 @@ If you are developing locally instead of using the published package:
|
|
|
182
185
|
"command": "node",
|
|
183
186
|
"args": [
|
|
184
187
|
"/absolute/path/to/agent-memory/dist/index.js"
|
|
185
|
-
]
|
|
186
|
-
"env": {
|
|
187
|
-
"AGENT_MEMORY_DB_PATH": "/absolute/path/to/memory.db"
|
|
188
|
-
}
|
|
188
|
+
]
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
Build first:
|
|
195
|
-
|
|
196
194
|
```bash
|
|
197
|
-
bun install
|
|
198
|
-
bun run build
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
## Local Development
|
|
202
|
-
|
|
203
|
-
Only needed if you want to work on the project itself.
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
bun install
|
|
207
195
|
bun lint
|
|
208
196
|
bun test
|
|
209
|
-
bun run build
|
|
210
197
|
```
|
|
211
198
|
|
|
212
|
-
## Notes
|
|
213
|
-
|
|
214
|
-
- `better-sqlite3` stays external in the build so its native binding loads
|
|
215
|
-
correctly at runtime.
|
|
216
|
-
- Runtime output is Node-compatible and built to `dist/index.js`.
|
|
217
|
-
|
|
218
199
|
## License
|
|
219
200
|
|
|
220
201
|
MIT
|
package/dist/index.js
CHANGED
|
@@ -12464,7 +12464,7 @@ class StdioServerTransport {
|
|
|
12464
12464
|
}
|
|
12465
12465
|
}
|
|
12466
12466
|
// package.json
|
|
12467
|
-
var version2 = "0.0.
|
|
12467
|
+
var version2 = "0.0.9";
|
|
12468
12468
|
|
|
12469
12469
|
// src/config.ts
|
|
12470
12470
|
import { homedir } from "node:os";
|
|
@@ -19971,8 +19971,8 @@ class MemoryService {
|
|
|
19971
19971
|
const normalizedQuery = {
|
|
19972
19972
|
terms,
|
|
19973
19973
|
limit: requestedLimit * RECALL_CANDIDATE_LIMIT_MULTIPLIER,
|
|
19974
|
-
|
|
19975
|
-
|
|
19974
|
+
updatedAfter: input.updatedAfter,
|
|
19975
|
+
updatedBefore: input.updatedBefore
|
|
19976
19976
|
};
|
|
19977
19977
|
const results = await this.repository.search(normalizedQuery);
|
|
19978
19978
|
const reranked = rerankSearchResults(results, workspace);
|
|
@@ -20049,11 +20049,11 @@ var parseOptionalDate = (value, fieldName) => {
|
|
|
20049
20049
|
|
|
20050
20050
|
// src/tools/recall.ts
|
|
20051
20051
|
var recallInputSchema = {
|
|
20052
|
-
terms: array(string2()).min(1).describe("Search terms used to find relevant memories. Pass 2-5 short, distinctive items as separate array entries,
|
|
20052
|
+
terms: array(string2()).min(1).describe("Search terms used to find relevant memories. Pass 2-5 short, distinctive items as separate array entries. Focus on the topic, not the project name -- use workspace for project scoping. Prefer file names, APIs, feature names, or brief phrases. Avoid full sentences."),
|
|
20053
20053
|
limit: number2().int().min(1).max(MAX_LIMIT).optional().describe("Maximum number of matches to return. Keep this small when you only need the strongest hits."),
|
|
20054
|
-
workspace: string2().optional().describe("
|
|
20055
|
-
|
|
20056
|
-
|
|
20054
|
+
workspace: string2().optional().describe("Always pass the current working directory. Biases ranking toward the active project while still allowing cross-workspace matches. Memories saved without a workspace are treated as global and rank between matching and non-matching results."),
|
|
20055
|
+
updated_after: string2().optional().describe("Only return memories updated at or after this ISO 8601 timestamp. Use it when you need to narrow recall to newer context."),
|
|
20056
|
+
updated_before: string2().optional().describe("Only return memories updated at or before this ISO 8601 timestamp. Use it when you need to narrow recall to older context.")
|
|
20057
20057
|
};
|
|
20058
20058
|
var recallOutputSchema = {
|
|
20059
20059
|
results: array(object({
|
|
@@ -20066,17 +20066,17 @@ var recallOutputSchema = {
|
|
|
20066
20066
|
};
|
|
20067
20067
|
var registerRecallTool = (server, memoryService) => {
|
|
20068
20068
|
server.registerTool("recall", {
|
|
20069
|
-
description: "Recall previously saved context for the current task.
|
|
20069
|
+
description: "Recall previously saved context for the current task. Call this at the start of every conversation and whenever prior preferences, decisions, or project context may be relevant. Pass workspace to bias results toward the active project.",
|
|
20070
20070
|
inputSchema: recallInputSchema,
|
|
20071
20071
|
outputSchema: recallOutputSchema
|
|
20072
|
-
}, async ({ terms, limit, workspace,
|
|
20072
|
+
}, async ({ terms, limit, workspace, updated_after, updated_before }) => {
|
|
20073
20073
|
try {
|
|
20074
20074
|
const results = await memoryService.search({
|
|
20075
20075
|
terms,
|
|
20076
20076
|
limit,
|
|
20077
20077
|
workspace,
|
|
20078
|
-
|
|
20079
|
-
|
|
20078
|
+
updatedAfter: parseOptionalDate(updated_after, "updated_after"),
|
|
20079
|
+
updatedBefore: parseOptionalDate(updated_before, "updated_before")
|
|
20080
20080
|
});
|
|
20081
20081
|
const structuredContent = {
|
|
20082
20082
|
results: results.map((result) => ({
|
|
@@ -20106,15 +20106,15 @@ var registerRecallTool = (server, memoryService) => {
|
|
|
20106
20106
|
|
|
20107
20107
|
// src/tools/remember.ts
|
|
20108
20108
|
var rememberInputSchema = {
|
|
20109
|
-
content: string2().describe("The
|
|
20110
|
-
workspace: string2().optional().describe("
|
|
20109
|
+
content: string2().describe("The fact, preference, decision, or context to remember. Use a single self-contained sentence or short note. One fact per memory."),
|
|
20110
|
+
workspace: string2().optional().describe("Always pass the current working directory to scope this memory to a project. Omit only when the memory applies across all projects (global preference).")
|
|
20111
20111
|
};
|
|
20112
20112
|
var rememberOutputSchema = {
|
|
20113
20113
|
id: string2().describe("Stable identifier for the saved memory.")
|
|
20114
20114
|
};
|
|
20115
20115
|
var registerRememberTool = (server, memoryService) => {
|
|
20116
20116
|
server.registerTool("remember", {
|
|
20117
|
-
description: "Save durable context for later recall. Use this
|
|
20117
|
+
description: "Save durable context for later recall. Use this when the user corrects your approach, states a preference, a key decision or convention is established, or you learn project context not obvious from the code. Store one concise fact per memory. Do not store secrets, ephemeral task state, or information already in the codebase.",
|
|
20118
20118
|
inputSchema: rememberInputSchema,
|
|
20119
20119
|
outputSchema: rememberOutputSchema
|
|
20120
20120
|
}, async ({ content, workspace }) => {
|
|
@@ -20142,10 +20142,19 @@ var registerRememberTool = (server, memoryService) => {
|
|
|
20142
20142
|
};
|
|
20143
20143
|
|
|
20144
20144
|
// src/mcp-server.ts
|
|
20145
|
+
var SERVER_INSTRUCTIONS = [
|
|
20146
|
+
"Persistent memory for coding agents.",
|
|
20147
|
+
"Use `recall` at the start of every conversation and whenever prior preferences, decisions, or project context may be relevant.",
|
|
20148
|
+
"Use `remember` when the user corrects your approach, states a preference, a key decision is established, or you learn project context not obvious from the code.",
|
|
20149
|
+
"Always pass workspace (the current working directory) to scope results to the active project.",
|
|
20150
|
+
"Omit workspace only when saving a memory that applies across all projects."
|
|
20151
|
+
].join(" ");
|
|
20145
20152
|
var createMcpServer = (memoryService, version3) => {
|
|
20146
20153
|
const server = new McpServer({
|
|
20147
20154
|
name: "agent-memory",
|
|
20148
20155
|
version: version3
|
|
20156
|
+
}, {
|
|
20157
|
+
instructions: SERVER_INSTRUCTIONS
|
|
20149
20158
|
});
|
|
20150
20159
|
registerRememberTool(server, memoryService);
|
|
20151
20160
|
registerRecallTool(server, memoryService);
|
|
@@ -20259,13 +20268,13 @@ class SqliteMemoryRepository {
|
|
|
20259
20268
|
try {
|
|
20260
20269
|
const whereParams = [toFtsQuery(query.terms)];
|
|
20261
20270
|
const whereClauses = ["memories_fts MATCH ?"];
|
|
20262
|
-
if (query.
|
|
20263
|
-
whereClauses.push("m.
|
|
20264
|
-
whereParams.push(query.
|
|
20271
|
+
if (query.updatedAfter) {
|
|
20272
|
+
whereClauses.push("m.updated_at >= ?");
|
|
20273
|
+
whereParams.push(query.updatedAfter.getTime());
|
|
20265
20274
|
}
|
|
20266
|
-
if (query.
|
|
20267
|
-
whereClauses.push("m.
|
|
20268
|
-
whereParams.push(query.
|
|
20275
|
+
if (query.updatedBefore) {
|
|
20276
|
+
whereClauses.push("m.updated_at <= ?");
|
|
20277
|
+
whereParams.push(query.updatedBefore.getTime());
|
|
20269
20278
|
}
|
|
20270
20279
|
const params = [...whereParams, query.limit];
|
|
20271
20280
|
const statement = this.database.prepare(`
|