@jcyamacho/agent-memory 0.0.11 → 0.0.12

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.
Files changed (3) hide show
  1. package/README.md +33 -4
  2. package/dist/index.js +93 -30
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -3,10 +3,12 @@
3
3
  Persistent memory for MCP-powered coding agents.
4
4
 
5
5
  `agent-memory` is a stdio MCP server that gives your LLM durable memory backed
6
- by SQLite. It exposes two tools:
6
+ by SQLite. It exposes four tools:
7
7
 
8
8
  - `remember` -> save facts, decisions, preferences, and project context
9
9
  - `recall` -> retrieve the most relevant memories later
10
+ - `revise` -> update an existing memory when it becomes outdated
11
+ - `forget` -> delete a memory that is no longer relevant
10
12
 
11
13
  Use it when your agent should remember preferences, project facts, and prior
12
14
  decisions across sessions.
@@ -66,7 +68,10 @@ Optional LLM instructions to reinforce the MCP's built-in guidance:
66
68
  Use `recall` at the start of every conversation and again mid-task before
67
69
  making design choices or picking conventions. Use `remember` when the user
68
70
  corrects your approach, a key decision is established, or you learn project
69
- context not obvious from the code. Always pass workspace.
71
+ context not obvious from the code. Before saving, recall to check whether a
72
+ memory about the same fact already exists -- if so, use `revise` to update
73
+ it instead of creating a duplicate. Use `forget` to remove memories that
74
+ are wrong or no longer relevant. Always pass workspace.
70
75
  ```
71
76
 
72
77
  ## What It Stores
@@ -92,8 +97,7 @@ Opens at `http://localhost:6580`. Use `--port` to change:
92
97
  npx -y @jcyamacho/agent-memory --ui --port 9090
93
98
  ```
94
99
 
95
- The web UI uses the same database as the MCP server. LLM tools remain
96
- append-only; the web UI is the only way to edit or delete memories.
100
+ The web UI uses the same database as the MCP server.
97
101
 
98
102
  ## Tools
99
103
 
@@ -127,6 +131,31 @@ Output:
127
131
 
128
132
  - `results[]` with `id`, `content`, `score`, `workspace`, and `updated_at`
129
133
 
134
+ ### `revise`
135
+
136
+ Update the content of an existing memory.
137
+
138
+ Inputs:
139
+
140
+ - `id` -> the memory id from a previous recall result
141
+ - `content` -> replacement content for the memory
142
+
143
+ Output:
144
+
145
+ - `id`, `updated_at`
146
+
147
+ ### `forget`
148
+
149
+ Permanently delete a memory.
150
+
151
+ Inputs:
152
+
153
+ - `id` -> the memory id from a previous recall result
154
+
155
+ Output:
156
+
157
+ - `id`, `deleted`
158
+
130
159
  ## How Ranking Works
131
160
 
132
161
  `recall` uses a multi-signal ranking system to surface the most relevant
package/dist/index.js CHANGED
@@ -12464,7 +12464,7 @@ class StdioServerTransport {
12464
12464
  }
12465
12465
  }
12466
12466
  // package.json
12467
- var version2 = "0.0.11";
12467
+ var version2 = "0.0.12";
12468
12468
 
12469
12469
  // src/config.ts
12470
12470
  import { homedir } from "node:os";
@@ -19895,9 +19895,6 @@ var EMPTY_COMPLETION_RESULT = {
19895
19895
  }
19896
19896
  };
19897
19897
 
19898
- // src/memory-service.ts
19899
- import { randomUUID } from "node:crypto";
19900
-
19901
19898
  // src/errors.ts
19902
19899
  class MemoryError extends Error {
19903
19900
  code;
@@ -19929,6 +19926,55 @@ class PersistenceError extends MemoryError {
19929
19926
  }
19930
19927
  }
19931
19928
 
19929
+ // src/tools/shared.ts
19930
+ var toMcpError = (error2) => {
19931
+ if (error2 instanceof McpError) {
19932
+ return error2;
19933
+ }
19934
+ if (error2 instanceof MemoryError) {
19935
+ if (error2.code === "VALIDATION_ERROR" || error2.code === "NOT_FOUND") {
19936
+ return new McpError(ErrorCode.InvalidParams, error2.message);
19937
+ }
19938
+ return new McpError(ErrorCode.InternalError, error2.message);
19939
+ }
19940
+ const message = error2 instanceof Error ? error2.message : "Unknown server error.";
19941
+ return new McpError(ErrorCode.InternalError, message);
19942
+ };
19943
+ var escapeXml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
19944
+ var parseOptionalDate = (value, fieldName) => {
19945
+ if (!value) {
19946
+ return;
19947
+ }
19948
+ const date4 = new Date(value);
19949
+ if (Number.isNaN(date4.getTime())) {
19950
+ throw new MemoryError("VALIDATION_ERROR", `${fieldName} must be a valid ISO 8601 datetime.`);
19951
+ }
19952
+ return date4;
19953
+ };
19954
+
19955
+ // src/tools/forget.ts
19956
+ var forgetInputSchema = {
19957
+ id: string2().describe("The id of the memory to delete. Use the id returned by a previous recall result.")
19958
+ };
19959
+ var registerForgetTool = (server, memoryService) => {
19960
+ server.registerTool("forget", {
19961
+ description: "Permanently delete a memory that is wrong, obsolete, or no longer relevant. Pass the memory id from a previous recall result.",
19962
+ inputSchema: forgetInputSchema
19963
+ }, async ({ id }) => {
19964
+ try {
19965
+ await memoryService.forget({ id });
19966
+ return {
19967
+ content: [{ type: "text", text: `<memory id="${id.trim()}" deleted="true" />` }]
19968
+ };
19969
+ } catch (error2) {
19970
+ throw toMcpError(error2);
19971
+ }
19972
+ });
19973
+ };
19974
+
19975
+ // src/memory-service.ts
19976
+ import { randomUUID } from "node:crypto";
19977
+
19932
19978
  // src/memory.ts
19933
19979
  var toNormalizedScore = (value) => value;
19934
19980
 
@@ -19963,6 +20009,18 @@ class MemoryService {
19963
20009
  };
19964
20010
  return this.repository.save(memory);
19965
20011
  }
20012
+ async revise(input) {
20013
+ const content = input.content.trim();
20014
+ if (!content)
20015
+ throw new ValidationError("Memory content is required.");
20016
+ return this.repository.update(input.id, content);
20017
+ }
20018
+ async forget(input) {
20019
+ const id = input.id.trim();
20020
+ if (!id)
20021
+ throw new ValidationError("Memory id is required.");
20022
+ return this.repository.delete(id);
20023
+ }
19966
20024
  async search(input) {
19967
20025
  const terms = normalizeTerms(input.terms);
19968
20026
  if (terms.length === 0) {
@@ -20040,32 +20098,6 @@ function rerankSearchResults(results, workspace) {
20040
20098
  });
20041
20099
  }
20042
20100
 
20043
- // src/tools/shared.ts
20044
- var toMcpError = (error2) => {
20045
- if (error2 instanceof McpError) {
20046
- return error2;
20047
- }
20048
- if (error2 instanceof MemoryError) {
20049
- if (error2.code === "VALIDATION_ERROR") {
20050
- return new McpError(ErrorCode.InvalidParams, error2.message);
20051
- }
20052
- return new McpError(ErrorCode.InternalError, error2.message);
20053
- }
20054
- const message = error2 instanceof Error ? error2.message : "Unknown server error.";
20055
- return new McpError(ErrorCode.InternalError, message);
20056
- };
20057
- var escapeXml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
20058
- var parseOptionalDate = (value, fieldName) => {
20059
- if (!value) {
20060
- return;
20061
- }
20062
- const date4 = new Date(value);
20063
- if (Number.isNaN(date4.getTime())) {
20064
- throw new MemoryError("VALIDATION_ERROR", `${fieldName} must be a valid ISO 8601 datetime.`);
20065
- }
20066
- return date4;
20067
- };
20068
-
20069
20101
  // src/tools/recall.ts
20070
20102
  var recallInputSchema = {
20071
20103
  terms: array(string2()).min(1).describe("Search terms used to find relevant memories. Pass 2-5 short, distinctive items as separate array entries. Be specific: instead of 'preferences' or 'context', name the actual topic -- e.g. 'error handling', 'commit format', 'testing strategy'. Do not repeat the project or workspace name here -- use the workspace parameter for project scoping. Avoid full sentences."),
@@ -20131,11 +20163,40 @@ var registerRememberTool = (server, memoryService) => {
20131
20163
  });
20132
20164
  };
20133
20165
 
20166
+ // src/tools/revise.ts
20167
+ var reviseInputSchema = {
20168
+ id: string2().describe("The id of the memory to update. Use the id returned by a previous recall result."),
20169
+ content: string2().describe("The replacement content for the memory. Use a single self-contained sentence or short note. One fact per memory.")
20170
+ };
20171
+ var registerReviseTool = (server, memoryService) => {
20172
+ server.registerTool("revise", {
20173
+ description: "Update the content of an existing memory. Use when a previously saved memory is outdated or inaccurate and needs correction rather than deletion. Pass the memory id from a previous recall result.",
20174
+ inputSchema: reviseInputSchema
20175
+ }, async ({ id, content }) => {
20176
+ try {
20177
+ const memory = await memoryService.revise({ id, content });
20178
+ return {
20179
+ content: [
20180
+ {
20181
+ type: "text",
20182
+ text: `<memory id="${memory.id}" updated_at="${memory.updatedAt.toISOString()}" />`
20183
+ }
20184
+ ]
20185
+ };
20186
+ } catch (error2) {
20187
+ throw toMcpError(error2);
20188
+ }
20189
+ });
20190
+ };
20191
+
20134
20192
  // src/mcp-server.ts
20135
20193
  var SERVER_INSTRUCTIONS = [
20136
20194
  "Stores decisions, corrections, and context that cannot be derived from code or git history.",
20137
20195
  "Use `recall` at the start of every conversation and again mid-task before making design choices or picking conventions the user may have guided before.",
20138
20196
  "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.",
20197
+ "Before saving a new memory, recall to check whether a memory about the same fact already exists. If so, use `revise` to update it instead of creating a duplicate.",
20198
+ "Use `revise` when a previously saved memory is outdated or inaccurate and needs correction rather than deletion.",
20199
+ "Use `forget` to remove memories that are wrong, obsolete, or no longer relevant.",
20139
20200
  "Always pass workspace (the current working directory) to scope results to the active project.",
20140
20201
  "Omit workspace only when saving a memory that applies across all projects."
20141
20202
  ].join(" ");
@@ -20148,6 +20209,8 @@ var createMcpServer = (memoryService, version3) => {
20148
20209
  });
20149
20210
  registerRememberTool(server, memoryService);
20150
20211
  registerRecallTool(server, memoryService);
20212
+ registerReviseTool(server, memoryService);
20213
+ registerForgetTool(server, memoryService);
20151
20214
  return server;
20152
20215
  };
20153
20216
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jcyamacho/agent-memory",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.11",
4
+ "version": "0.0.12",
5
5
  "bin": {
6
6
  "agent-memory": "dist/index.js"
7
7
  },