@levalicious/server-memory 0.0.2 → 0.0.4

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 +59 -4
  2. package/dist/index.js +175 -105
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -125,6 +125,63 @@ Example:
125
125
  - Relations between requested entities
126
126
  - Silently skips non-existent nodes
127
127
 
128
+ - **get_neighbors**
129
+ - Get neighboring entities connected to a specific entity within a given depth
130
+ - Input: `entityName` (string), `depth` (number, default: 1)
131
+ - Returns entities connected within specified depth
132
+
133
+ - **find_path**
134
+ - Find a path between two entities in the knowledge graph
135
+ - Input: `fromEntity` (string), `toEntity` (string), `maxDepth` (number, default: 5)
136
+ - Returns path between entities if one exists
137
+
138
+ - **get_entities_by_type**
139
+ - Get all entities of a specific type
140
+ - Input: `entityType` (string)
141
+ - Returns all entities matching the specified type
142
+
143
+ - **get_entity_types**
144
+ - Get all unique entity types in the knowledge graph
145
+ - No input required
146
+ - Returns list of all entity types
147
+
148
+ - **get_relation_types**
149
+ - Get all unique relation types in the knowledge graph
150
+ - No input required
151
+ - Returns list of all relation types
152
+
153
+ - **get_stats**
154
+ - Get statistics about the knowledge graph
155
+ - No input required
156
+ - Returns entity count, relation count, entity types count, relation types count
157
+
158
+ - **get_orphaned_entities**
159
+ - Get entities that have no relations
160
+ - No input required
161
+ - Returns entities with no connections
162
+
163
+ - **validate_graph**
164
+ - Validate the knowledge graph and return missing entities referenced in relations
165
+ - No input required
166
+ - Returns list of missing entities
167
+
168
+ - **evaluate_bcl**
169
+ - Evaluate a Binary Combinatory Logic (BCL) program
170
+ - Input: `program` (string), `maxSteps` (number, default: 1000000)
171
+ - BCL syntax: T:=00|01|1TT where 00=K, 01=S, 1=application
172
+ - Returns evaluation result with halt status
173
+
174
+ - **add_bcl_term**
175
+ - Add a BCL term to the constructor, maintaining valid syntax
176
+ - Input: `term` (string)
177
+ - Valid values: '1' or 'App' (application), '00' or 'K' (K combinator), '01' or 'S' (S combinator)
178
+ - Returns completion status
179
+
180
+ - **clear_bcl_term**
181
+ - Clear the current BCL term being constructed and reset the constructor state
182
+ - No input required
183
+ - Resets BCL constructor
184
+
128
185
  # Usage with Claude Desktop
129
186
 
130
187
  ### Setup
@@ -186,9 +243,7 @@ The server can be configured using the following environment variables:
186
243
 
187
244
  For quick installation, use one of the one-click installation buttons below:
188
245
 
189
- [![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-memory%22%5D%7D) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-NPM-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40modelcontextprotocol%2Fserver-memory%22%5D%7D&quality=insiders)
190
-
191
- [![Install with Docker in VS Code](https://img.shields.io/badge/VS_Code-Docker-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22-v%22%2C%22claude-memory%3A%2Fapp%2Fdist%22%2C%22--rm%22%2C%22mcp%2Fmemory%22%5D%7D) [![Install with Docker in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Docker-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22docker%22%2C%22args%22%3A%5B%22run%22%2C%22-i%22%2C%22-v%22%2C%22claude-memory%3A%2Fapp%2Fdist%22%2C%22--rm%22%2C%22mcp%2Fmemory%22%5D%7D&quality=insiders)
246
+ [![Install with NPX in VS Code](https://img.shields.io/badge/VS_Code-NPM-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40levalicious%2Fserver-memory%22%5D%7D) [![Install with NPX in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-NPM-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=memory&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40levalicious%2Fserver-memory%22%5D%7D&quality=insiders)
192
247
 
193
248
  For manual installation, add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open Settings (JSON)`.
194
249
 
@@ -278,4 +333,4 @@ docker build -t mcp/memory -f src/memory/Dockerfile .
278
333
 
279
334
  ## License
280
335
 
281
- This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
336
+ This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
package/dist/index.js CHANGED
@@ -15,6 +15,8 @@ const MEMORY_FILE_PATH = process.env.MEMORY_FILE_PATH
15
15
  : defaultMemoryPath;
16
16
  // The KnowledgeGraphManager class contains all operations to interact with the knowledge graph
17
17
  class KnowledgeGraphManager {
18
+ bclCtr = 0;
19
+ bclTerm = "";
18
20
  async loadGraph() {
19
21
  try {
20
22
  const data = await fs.readFile(MEMORY_FILE_PATH, "utf-8");
@@ -243,133 +245,174 @@ class KnowledgeGraphManager {
243
245
  }
244
246
  // BCL (Binary Combinatory Logic) evaluator
245
247
  async evaluateBCL(program, maxSteps) {
246
- let current = program;
247
248
  let stepCount = 0;
248
- // Find and apply one reduction rule to the leftmost applicable position
249
- const applyOneRule = (term) => {
250
- // Scan left-to-right for rule applications
251
- for (let pos = 0; pos <= term.length - 6; pos++) { // minimum pattern "1100xy" needs at least 6 chars
252
- // Rule 1: 1100xy → x
253
- if (pos <= term.length - 6 && term.substring(pos, pos + 4) === '1100') {
254
- let parsePos = pos + 4;
255
- // Parse x
256
- const xResult = this.parseBCLTerm(term, parsePos);
257
- if (xResult.success) {
258
- parsePos = xResult.nextPos;
259
- // Parse y
260
- const yResult = this.parseBCLTerm(term, parsePos);
261
- if (yResult.success) {
262
- // Apply Rule 1: 1100xy → x
263
- const before = term.substring(0, pos);
264
- const after = term.substring(yResult.nextPos);
265
- const newTerm = before + xResult.term + after;
266
- return {
267
- newTerm,
268
- applied: true,
269
- rule: `Rule 1: 1100${xResult.term}${yResult.term} → ${xResult.term}`
270
- };
271
- }
272
- }
249
+ let max_size = program.length;
250
+ let mode = 0;
251
+ let ctr = 1;
252
+ let t0 = program;
253
+ let t1 = '';
254
+ let t2 = '';
255
+ let t3 = '';
256
+ let t4 = '';
257
+ while (stepCount < maxSteps) {
258
+ if (t0.length == 0)
259
+ break;
260
+ let b = t0[0];
261
+ t0 = t0.slice(1);
262
+ if (mode === 0) {
263
+ t1 += b;
264
+ let size = t1.length + t0.length;
265
+ if (size > max_size)
266
+ max_size = size;
267
+ if (t1.slice(-4) === '1100') {
268
+ mode = 1;
269
+ t1 = t1.slice(0, -4);
273
270
  }
274
- // Rule 2: 11101xyz → 11xz1yz (need minimum 8 chars)
275
- if (pos <= term.length - 8 && term.substring(pos, pos + 5) === '11101') {
276
- let parsePos = pos + 5;
277
- // Parse x
278
- const xResult = this.parseBCLTerm(term, parsePos);
279
- if (xResult.success) {
280
- parsePos = xResult.nextPos;
281
- // Parse y
282
- const yResult = this.parseBCLTerm(term, parsePos);
283
- if (yResult.success) {
284
- parsePos = yResult.nextPos;
285
- // Parse z
286
- const zResult = this.parseBCLTerm(term, parsePos);
287
- if (zResult.success) {
288
- // Apply Rule 2: 11101xyz → 11xz1yz
289
- const x = xResult.term;
290
- const y = yResult.term;
291
- const z = zResult.term;
292
- const before = term.substring(0, pos);
293
- const after = term.substring(zResult.nextPos);
294
- const replacement = `11${x}${z}1${y}${z}`;
295
- const newTerm = before + replacement + after;
296
- return {
297
- newTerm,
298
- applied: true,
299
- rule: `Rule 2: 11101${x}${y}${z} → 11${x}${z}1${y}${z}`
300
- };
301
- }
302
- }
303
- }
271
+ else if (t1.slice(-5) === '11101') {
272
+ mode = 3;
273
+ t1 = t1.slice(0, -5);
304
274
  }
305
275
  }
306
- return { newTerm: term, applied: false, rule: '' };
307
- };
308
- // Validate input is a well-formed BCL term
309
- const validation = this.parseBCLTerm(current, 0);
310
- if (!validation.success || validation.nextPos !== current.length) {
311
- return {
312
- result: current,
313
- info: `Error: Invalid BCL term - parse failed at position ${validation.nextPos}`,
314
- halted: false
315
- };
316
- }
317
- let max_size = current.length;
318
- while (stepCount < maxSteps) {
319
- const result = applyOneRule(current);
320
- if (!result.applied) {
321
- // Normal form reached - no more reductions possible
322
- break;
276
+ else if (mode === 1) {
277
+ t2 += b;
278
+ if (b == '1') {
279
+ ctr += 1;
280
+ }
281
+ else if (b == '0') {
282
+ ctr -= 1;
283
+ t2 += t0[0];
284
+ t0 = t0.slice(1);
285
+ }
286
+ if (ctr === 0) {
287
+ mode = 2;
288
+ ctr = 1;
289
+ }
290
+ }
291
+ else if (mode === 2) {
292
+ if (b == '1') {
293
+ ctr += 1;
294
+ }
295
+ else if (b == '0') {
296
+ ctr -= 1;
297
+ t0 = t0.slice(1);
298
+ }
299
+ if (ctr === 0) {
300
+ t0 = t2 + t0;
301
+ t2 = '';
302
+ mode = 0;
303
+ ctr = 1;
304
+ stepCount += 1;
305
+ }
306
+ }
307
+ else if (mode === 3) {
308
+ t2 += b;
309
+ if (b == '1') {
310
+ ctr += 1;
311
+ }
312
+ else if (b == '0') {
313
+ ctr -= 1;
314
+ t2 += t0[0];
315
+ t0 = t0.slice(1);
316
+ }
317
+ if (ctr === 0) {
318
+ mode = 4;
319
+ ctr = 1;
320
+ }
323
321
  }
324
- current = result.newTerm;
325
- if (current.length > max_size) {
326
- max_size = current.length;
322
+ else if (mode === 4) {
323
+ t3 += b;
324
+ if (b == '1') {
325
+ ctr += 1;
326
+ }
327
+ else if (b == '0') {
328
+ ctr -= 1;
329
+ t3 += t0[0];
330
+ t0 = t0.slice(1);
331
+ }
332
+ if (ctr === 0) {
333
+ mode = 5;
334
+ ctr = 1;
335
+ }
336
+ }
337
+ else if (mode === 5) {
338
+ t4 += b;
339
+ if (b == '1') {
340
+ ctr += 1;
341
+ }
342
+ else if (b == '0') {
343
+ ctr -= 1;
344
+ t4 += t0[0];
345
+ t0 = t0.slice(1);
346
+ }
347
+ if (ctr === 0) {
348
+ t0 = '11' + t2 + t4 + '1' + t3 + t4 + t0;
349
+ t2 = '';
350
+ t3 = '';
351
+ t4 = '';
352
+ mode = 0;
353
+ ctr = 1;
354
+ stepCount += 1;
355
+ }
327
356
  }
328
- stepCount++;
329
357
  }
330
358
  const halted = stepCount < maxSteps;
331
359
  return {
332
- result: current,
360
+ result: t1,
333
361
  info: `${stepCount} steps, max size ${max_size}`,
334
- halted
362
+ halted,
363
+ errored: halted && mode != 0,
335
364
  };
336
365
  }
337
- // Helper function to parse a single BCL term from a given position
338
- parseBCLTerm(input, startPos) {
339
- if (startPos >= input.length) {
340
- return { success: false, term: '', nextPos: startPos };
366
+ async addBCLTerm(term) {
367
+ const termset = ["1", "00", "01"];
368
+ if (!term || term.trim() === "") {
369
+ throw new Error("BCL term cannot be empty");
341
370
  }
342
- // Check for 00 (K combinator)
343
- if (startPos + 1 < input.length && input.substring(startPos, startPos + 2) === '00') {
344
- return { success: true, term: '00', nextPos: startPos + 2 };
371
+ // Term can be 1, 00, 01, or K, S, App (application)
372
+ const validTerms = ["1", "App", "00", "K", "01", "S"];
373
+ if (!validTerms.includes(term)) {
374
+ throw new Error(`Invalid BCL term: ${term}\nExpected one of: ${validTerms.join(", ")}`);
345
375
  }
346
- // Check for 01 (S combinator)
347
- if (startPos + 1 < input.length && input.substring(startPos, startPos + 2) === '01') {
348
- return { success: true, term: '01', nextPos: startPos + 2 };
376
+ let processedTerm = 0;
377
+ if (term === "00" || term === "K")
378
+ processedTerm = 1;
379
+ else if (term === "01" || term === "S")
380
+ processedTerm = 2;
381
+ this.bclTerm += termset[processedTerm];
382
+ if (processedTerm === 0) {
383
+ if (this.bclCtr === 0)
384
+ this.bclCtr += 1;
385
+ this.bclCtr += 1;
349
386
  }
350
- // Check for 1 (application)
351
- if (input[startPos] === '1') {
352
- // Parse first subterm
353
- const leftResult = this.parseBCLTerm(input, startPos + 1);
354
- if (!leftResult.success) {
355
- return leftResult;
356
- }
357
- // Parse second subterm
358
- const rightResult = this.parseBCLTerm(input, leftResult.nextPos);
359
- if (!rightResult.success) {
360
- return rightResult;
361
- }
362
- const term = '1' + leftResult.term + rightResult.term;
363
- return { success: true, term, nextPos: rightResult.nextPos };
387
+ else {
388
+ this.bclCtr -= 1;
389
+ }
390
+ if (this.bclCtr <= 0) {
391
+ const constructedProgram = this.bclTerm;
392
+ this.bclCtr = 0;
393
+ this.bclTerm = "";
394
+ return `Constructed Program: ${constructedProgram}`;
395
+ }
396
+ else {
397
+ return `Need ${this.bclCtr} more term(s) to complete the program.`;
364
398
  }
365
- return { success: false, term: '', nextPos: startPos };
399
+ }
400
+ async clearBCLTerm() {
401
+ this.bclCtr = 0;
402
+ this.bclTerm = "";
366
403
  }
367
404
  }
368
405
  const knowledgeGraphManager = new KnowledgeGraphManager();
369
406
  // The server instance and tools exposed to Claude
370
407
  const server = new Server({
371
408
  name: "memory-server",
372
- version: "0.0.0",
409
+ icons: [
410
+ { src: "data:image/svg+xml;base64,PHN2ZyBmaWxsPSJjdXJyZW50Q29sb3IiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxZW0iIHN0eWxlPSJmbGV4Om5vbmU7bGluZS1oZWlnaHQ6MSIgdmlld0JveD0iMCAwIDI0IDI0IiB3aWR0aD0iMWVtIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5Nb2RlbENvbnRleHRQcm90b2NvbDwvdGl0bGU+PHBhdGggZD0iTTIwLjEgNS41MlYxLjVoLS4xOGMtMy4zNi4xNS02LjE1IDIuMzEtNy44MyA0LjAybC0uMDkuMDktLjA5LS4wOUMxMC4yIDMuODEgNy40NCAxLjY1IDQuMDggMS41SDMuOXY0LjAySDB2Ni45M2MwIDEuNjguMDYgMy4zNi4xOCA0Ljc0YTUuNTcgNS41NyAwIDAgMCA1LjE5IDUuMWMyLjEzLjEyIDQuMzguMjEgNi42My4yMXM0LjUtLjA5IDYuNjMtLjI0YTUuNTcgNS41NyAwIDAgMCA1LjE5LTUuMWMuMTItMS4zOC4xOC0zLjA2LjE4LTQuNzR2LTYuOXptMCA2LjkzYzAgMS41OS0uMDYgMy4xNS0uMTggNC40MS0uMDkuODEtLjc1IDEuNDctMS41NiAxLjVhOTAgOTAgMCAwIDEtMTIuNzIgMGMtLjgxLS4wMy0xLjUtLjY5LTEuNTYtMS41LS4xMi0xLjI2LS4xOC0yLjg1LS4xOC00LjQxVjUuNTJjMi44Mi4xMiA1LjY0IDMuMTUgNi40OCA0LjMyTDEyIDEyLjA5bDEuNjItMi4yNWMuODQtMS4yIDMuNjYtNC4yIDYuNDgtNC4zMnoiLz48L3N2Zz4=",
411
+ mimeType: "image/svg+xml",
412
+ sizes: ["any"]
413
+ }
414
+ ],
415
+ version: "0.0.4",
373
416
  }, {
374
417
  capabilities: {
375
418
  tools: {},
@@ -651,6 +694,28 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
651
694
  required: ["program"],
652
695
  },
653
696
  },
697
+ {
698
+ name: "add_bcl_term",
699
+ description: "Add a BCL term to the constructor, maintaining valid syntax. Returns completion status.",
700
+ inputSchema: {
701
+ type: "object",
702
+ properties: {
703
+ term: {
704
+ type: "string",
705
+ description: "BCL term to add. Valid values: '1' or 'App' (application), '00' or 'K' (K combinator), '01' or 'S' (S combinator)"
706
+ },
707
+ },
708
+ required: ["term"],
709
+ },
710
+ },
711
+ {
712
+ name: "clear_bcl_term",
713
+ description: "Clear the current BCL term being constructed and reset the constructor state",
714
+ inputSchema: {
715
+ type: "object",
716
+ properties: {},
717
+ },
718
+ },
654
719
  ],
655
720
  };
656
721
  });
@@ -701,6 +766,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
701
766
  return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.validateGraph(), null, 2) }] };
702
767
  case "evaluate_bcl":
703
768
  return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.evaluateBCL(args.program, args.maxSteps), null, 2) }] };
769
+ case "add_bcl_term":
770
+ return { content: [{ type: "text", text: await knowledgeGraphManager.addBCLTerm(args.term) }] };
771
+ case "clear_bcl_term":
772
+ await knowledgeGraphManager.clearBCLTerm();
773
+ return { content: [{ type: "text", text: "BCL term constructor cleared successfully" }] };
704
774
  default:
705
775
  throw new Error(`Unknown tool: ${name}`);
706
776
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levalicious/server-memory",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "MCP server for enabling memory for Claude through a knowledge graph",
5
5
  "license": "MIT",
6
6
  "author": "Levalicious",
@@ -19,7 +19,7 @@
19
19
  "watch": "tsc --watch"
20
20
  },
21
21
  "dependencies": {
22
- "@modelcontextprotocol/sdk": "1.16.0"
22
+ "@modelcontextprotocol/sdk": "1.21.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^24",