@plures/superlocalmemory-mcp 0.2.0
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/LICENSE +661 -0
- package/README.md +228 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/db/memory.d.ts +95 -0
- package/dist/db/memory.d.ts.map +1 -0
- package/dist/db/memory.js +245 -0
- package/dist/db/memory.js.map +1 -0
- package/dist/embeddings/index.d.ts +16 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +26 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/openai.d.ts +17 -0
- package/dist/embeddings/openai.d.ts.map +1 -0
- package/dist/embeddings/openai.js +62 -0
- package/dist/embeddings/openai.js.map +1 -0
- package/dist/embeddings/transformers.d.ts +18 -0
- package/dist/embeddings/transformers.d.ts.map +1 -0
- package/dist/embeddings/transformers.js +59 -0
- package/dist/embeddings/transformers.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +378 -0
- package/dist/server.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EmbeddingProvider } from "./transformers.js";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI embedding provider (optional, requires openai package and API key).
|
|
4
|
+
* Uses text-embedding-3-small with 1536 dimensions.
|
|
5
|
+
* Uses dynamic ES module import for better compatibility with ES module projects.
|
|
6
|
+
*/
|
|
7
|
+
export declare class OpenAIEmbeddings implements EmbeddingProvider {
|
|
8
|
+
readonly dimension = 1536;
|
|
9
|
+
private apiKey;
|
|
10
|
+
private model;
|
|
11
|
+
private debug;
|
|
12
|
+
private clientPromise;
|
|
13
|
+
constructor(apiKey: string, model?: string, debug?: boolean);
|
|
14
|
+
private getClient;
|
|
15
|
+
embed(text: string): Promise<number[]>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/embeddings/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,SAAgB,SAAS,QAAQ;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,aAAa,CAA6B;gBAEtC,MAAM,EAAE,MAAM,EAAE,KAAK,SAA2B,EAAE,KAAK,UAAQ;YAY7D,SAAS;IA2BjB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CA4B7C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI embedding provider (optional, requires openai package and API key).
|
|
3
|
+
* Uses text-embedding-3-small with 1536 dimensions.
|
|
4
|
+
* Uses dynamic ES module import for better compatibility with ES module projects.
|
|
5
|
+
*/
|
|
6
|
+
export class OpenAIEmbeddings {
|
|
7
|
+
dimension = 1536;
|
|
8
|
+
apiKey;
|
|
9
|
+
model;
|
|
10
|
+
debug;
|
|
11
|
+
clientPromise = null;
|
|
12
|
+
constructor(apiKey, model = "text-embedding-3-small", debug = false) {
|
|
13
|
+
this.apiKey = apiKey;
|
|
14
|
+
this.model = model;
|
|
15
|
+
this.debug = debug;
|
|
16
|
+
if (this.debug) {
|
|
17
|
+
console.error(`[OpenAIEmbeddings] Configured for lazy initialization with model ${this.model}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async getClient() {
|
|
21
|
+
if (!this.clientPromise) {
|
|
22
|
+
this.clientPromise = (async () => {
|
|
23
|
+
try {
|
|
24
|
+
// Dynamic import to make openai optional in an ES module context
|
|
25
|
+
const openaiModule = await import("openai");
|
|
26
|
+
const OpenAI = openaiModule.default || openaiModule;
|
|
27
|
+
const client = new OpenAI({ apiKey: this.apiKey });
|
|
28
|
+
if (this.debug) {
|
|
29
|
+
console.error(`[OpenAIEmbeddings] Initialized OpenAI client with model ${this.model}`);
|
|
30
|
+
}
|
|
31
|
+
return client;
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
throw new Error("OpenAI package not available. Install with: npm install openai");
|
|
35
|
+
}
|
|
36
|
+
})();
|
|
37
|
+
}
|
|
38
|
+
return this.clientPromise;
|
|
39
|
+
}
|
|
40
|
+
async embed(text) {
|
|
41
|
+
try {
|
|
42
|
+
const client = await this.getClient();
|
|
43
|
+
const response = await client.embeddings.create({
|
|
44
|
+
model: this.model,
|
|
45
|
+
input: text,
|
|
46
|
+
});
|
|
47
|
+
const embedding = response.data[0].embedding;
|
|
48
|
+
// Validate dimension
|
|
49
|
+
if (embedding.length !== this.dimension) {
|
|
50
|
+
throw new Error(`Expected ${this.dimension}-dim embedding but got ${embedding.length}-dim from OpenAI`);
|
|
51
|
+
}
|
|
52
|
+
if (this.debug) {
|
|
53
|
+
console.error(`[OpenAIEmbeddings] Generated embedding of dimension ${embedding.length} for text of length ${text.length}`);
|
|
54
|
+
}
|
|
55
|
+
return embedding;
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new Error(`OpenAI embedding failed: ${err.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/embeddings/openai.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IACX,SAAS,GAAG,IAAI,CAAC;IACzB,MAAM,CAAS;IACf,KAAK,CAAS;IACd,KAAK,CAAU;IACf,aAAa,GAAwB,IAAI,CAAC;IAElD,YAAY,MAAc,EAAE,KAAK,GAAG,wBAAwB,EAAE,KAAK,GAAG,KAAK;QACzE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,oEAAoE,IAAI,CAAC,KAAK,EAAE,CACjF,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC/B,IAAI,CAAC;oBACH,iEAAiE;oBACjE,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;oBAC5C,MAAM,MAAM,GAAI,YAAoB,CAAC,OAAO,IAAI,YAAY,CAAC;oBAC7D,MAAM,MAAM,GAAG,IAAK,MAAc,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;oBAE5D,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;wBACf,OAAO,CAAC,KAAK,CACX,2DAA2D,IAAI,CAAC,KAAK,EAAE,CACxE,CAAC;oBACJ,CAAC;oBAED,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QAED,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC9C,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI;aACZ,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAE7C,qBAAqB;YACrB,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,CAAC,SAAS,0BAA0B,SAAS,CAAC,MAAM,kBAAkB,CACvF,CAAC;YACJ,CAAC;YAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CACX,uDAAuD,SAAS,CAAC,MAAM,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAC5G,CAAC;YACJ,CAAC;YAED,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,4BAA6B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface EmbeddingProvider {
|
|
2
|
+
embed(text: string): Promise<number[]>;
|
|
3
|
+
dimension: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Transformers.js embedding provider using bge-small-en-v1.5 (384 dimensions).
|
|
7
|
+
* This runs entirely in-process with no external API calls (after initial model download).
|
|
8
|
+
*/
|
|
9
|
+
export declare class TransformersEmbeddings implements EmbeddingProvider {
|
|
10
|
+
readonly dimension = 384;
|
|
11
|
+
private pipeline;
|
|
12
|
+
private readonly model;
|
|
13
|
+
private debug;
|
|
14
|
+
constructor(debug?: boolean);
|
|
15
|
+
private ensurePipeline;
|
|
16
|
+
embed(text: string): Promise<number[]>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=transformers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers.d.ts","sourceRoot":"","sources":["../../src/embeddings/transformers.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;CACnB;AAQD;;;GAGG;AACH,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,SAAgB,SAAS,OAAO;IAChC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,OAAO,CAAC,KAAK,CAAU;gBAEX,KAAK,UAAQ;YAIX,cAAc;IAyBtB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAsB7C"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { pipeline, env } from "@huggingface/transformers";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
// Configure cache directory (customizable via environment variable)
|
|
5
|
+
const cacheDir = process.env.SUPERLOCALMEMORY_CACHE_DIR ||
|
|
6
|
+
path.join(os.homedir(), ".cache", "superlocalmemory", "transformers");
|
|
7
|
+
env.cacheDir = cacheDir;
|
|
8
|
+
env.allowLocalModels = true;
|
|
9
|
+
env.allowRemoteModels = true;
|
|
10
|
+
/**
|
|
11
|
+
* Transformers.js embedding provider using bge-small-en-v1.5 (384 dimensions).
|
|
12
|
+
* This runs entirely in-process with no external API calls (after initial model download).
|
|
13
|
+
*/
|
|
14
|
+
export class TransformersEmbeddings {
|
|
15
|
+
dimension = 384;
|
|
16
|
+
pipeline = null;
|
|
17
|
+
model = "Xenova/bge-small-en-v1.5";
|
|
18
|
+
debug;
|
|
19
|
+
constructor(debug = false) {
|
|
20
|
+
this.debug = debug;
|
|
21
|
+
}
|
|
22
|
+
async ensurePipeline() {
|
|
23
|
+
if (!this.pipeline) {
|
|
24
|
+
if (this.debug) {
|
|
25
|
+
console.error(`[TransformersEmbeddings] Loading model ${this.model}...`);
|
|
26
|
+
console.error(`[TransformersEmbeddings] Cache directory: ${cacheDir}`);
|
|
27
|
+
console.error(`[TransformersEmbeddings] Note: First run will download the model (~100MB), subsequent runs use cache`);
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
this.pipeline = (await pipeline("feature-extraction", this.model));
|
|
31
|
+
if (this.debug) {
|
|
32
|
+
console.error(`[TransformersEmbeddings] Model loaded successfully`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const error = err;
|
|
37
|
+
throw new Error(`Failed to load embedding model: ${error.message}. ` +
|
|
38
|
+
`This may be due to network restrictions or missing model files. ` +
|
|
39
|
+
`Try running with network access first to download the model, or set OPENAI_API_KEY as fallback.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return this.pipeline;
|
|
43
|
+
}
|
|
44
|
+
async embed(text) {
|
|
45
|
+
const pipe = await this.ensurePipeline();
|
|
46
|
+
// Generate embeddings
|
|
47
|
+
const output = await pipe(text, { pooling: "mean", normalize: true });
|
|
48
|
+
// Convert to regular array
|
|
49
|
+
const embedding = Array.from(output.data);
|
|
50
|
+
if (this.debug) {
|
|
51
|
+
console.error(`[TransformersEmbeddings] Generated embedding of dimension ${embedding.length} for text of length ${text.length}`);
|
|
52
|
+
}
|
|
53
|
+
if (embedding.length !== this.dimension) {
|
|
54
|
+
throw new Error(`Expected ${this.dimension}-dim embedding but got ${embedding.length}-dim`);
|
|
55
|
+
}
|
|
56
|
+
return embedding;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=transformers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformers.js","sourceRoot":"","sources":["../../src/embeddings/transformers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,oEAAoE;AACpE,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,0BAA0B;IACtC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,cAAc,CAAC,CAAC;AACxE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;AACxB,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC;AAC5B,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC;AAa7B;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IACjB,SAAS,GAAG,GAAG,CAAC;IACxB,QAAQ,GAA6B,IAAI,CAAC;IACjC,KAAK,GAAG,0BAA0B,CAAC;IAC5C,KAAK,CAAU;IAEvB,YAAY,KAAK,GAAG,KAAK;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEO,KAAK,CAAC,cAAc;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;gBACzE,OAAO,CAAC,KAAK,CAAC,6CAA6C,QAAQ,EAAE,CAAC,CAAC;gBACvE,OAAO,CAAC,KAAK,CAAC,sGAAsG,CAAC,CAAC;YACxH,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,CAAC,QAAQ,GAAG,CAAC,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,KAAK,CAAC,CAA6B,CAAC;gBAC/F,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,GAAY,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,mCAAmC,KAAK,CAAC,OAAO,IAAI;oBACpD,kEAAkE;oBAClE,iGAAiG,CAClG,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAEzC,sBAAsB;QACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtE,2BAA2B;QAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAa,CAAC;QAEtD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,6DAA6D,SAAS,CAAC,MAAM,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAClH,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,CAAC,SAAS,0BAA0B,SAAS,CAAC,MAAM,MAAM,CAC3E,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,uBAAuB;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,WAAW,EAAE,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAsFA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyVjD"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { CallToolRequestSchema, ErrorCode, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
import { MemoryDB } from "./db/memory.js";
|
|
7
|
+
import { createEmbeddings } from "./embeddings/index.js";
|
|
8
|
+
import { loadConfig } from "./config.js";
|
|
9
|
+
function textResult(toolResult) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult, null, 2),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
toolResult,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function asStringArray(v) {
|
|
21
|
+
if (v === undefined || v === null)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (!Array.isArray(v))
|
|
24
|
+
throw new McpError(ErrorCode.InvalidParams, "Expected an array");
|
|
25
|
+
return v.map((x) => String(x));
|
|
26
|
+
}
|
|
27
|
+
async function ensureParentDir(filePath) {
|
|
28
|
+
const dir = path.dirname(filePath);
|
|
29
|
+
await fs.mkdir(dir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
async function* walkDir(root, opts) {
|
|
32
|
+
const ignore = new Set(opts?.ignore ?? []);
|
|
33
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
34
|
+
for (const ent of entries) {
|
|
35
|
+
if (ignore.has(ent.name))
|
|
36
|
+
continue;
|
|
37
|
+
const p = path.join(root, ent.name);
|
|
38
|
+
if (ent.isDirectory()) {
|
|
39
|
+
yield* walkDir(p, opts);
|
|
40
|
+
}
|
|
41
|
+
else if (ent.isFile()) {
|
|
42
|
+
yield p;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function shouldIndexFile(filePath) {
|
|
47
|
+
const base = path.basename(filePath);
|
|
48
|
+
if (base.startsWith("."))
|
|
49
|
+
return false;
|
|
50
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
51
|
+
return [
|
|
52
|
+
".md",
|
|
53
|
+
".txt",
|
|
54
|
+
".ts",
|
|
55
|
+
".tsx",
|
|
56
|
+
".js",
|
|
57
|
+
".jsx",
|
|
58
|
+
".json",
|
|
59
|
+
".yml",
|
|
60
|
+
".yaml",
|
|
61
|
+
".py",
|
|
62
|
+
".go",
|
|
63
|
+
".rs",
|
|
64
|
+
".java",
|
|
65
|
+
".kt",
|
|
66
|
+
".swift",
|
|
67
|
+
".rb",
|
|
68
|
+
".php",
|
|
69
|
+
".toml",
|
|
70
|
+
".ini",
|
|
71
|
+
].includes(ext);
|
|
72
|
+
}
|
|
73
|
+
export async function startServer() {
|
|
74
|
+
const config = loadConfig();
|
|
75
|
+
await ensureParentDir(config.dbPath);
|
|
76
|
+
// Create embeddings provider (defaults to Transformers.js, optional OpenAI)
|
|
77
|
+
const embeddings = await createEmbeddings({
|
|
78
|
+
openaiApiKey: config.openaiApiKey,
|
|
79
|
+
openaiModel: config.openaiModel,
|
|
80
|
+
debug: config.debug,
|
|
81
|
+
});
|
|
82
|
+
const db = new MemoryDB(config.dbPath, embeddings.dimension);
|
|
83
|
+
const server = new Server({ name: "superlocalmemory-mcp", version: "0.1.0" }, {
|
|
84
|
+
capabilities: {
|
|
85
|
+
tools: {},
|
|
86
|
+
resources: {},
|
|
87
|
+
},
|
|
88
|
+
instructions: "Persistent local vector memory backed by SQLite. Use memory_store to save, memory_search to recall, and memory_index to ingest a codebase.",
|
|
89
|
+
});
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Tools
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
94
|
+
return {
|
|
95
|
+
tools: [
|
|
96
|
+
{
|
|
97
|
+
name: "memory_store",
|
|
98
|
+
description: "Store a memory (content) with optional tags and category.",
|
|
99
|
+
inputSchema: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
content: { type: "string", description: "The memory text to store." },
|
|
103
|
+
tags: { type: "array", items: { type: "string" }, description: "Optional tags." },
|
|
104
|
+
category: { type: "string", description: "Optional category (e.g., decision, preference, project)." },
|
|
105
|
+
source: { type: "string", description: "Optional source label." },
|
|
106
|
+
},
|
|
107
|
+
required: ["content"],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: "memory_search",
|
|
112
|
+
description: "Semantic search across memories.",
|
|
113
|
+
inputSchema: {
|
|
114
|
+
type: "object",
|
|
115
|
+
properties: {
|
|
116
|
+
query: { type: "string", description: "Search query." },
|
|
117
|
+
limit: { type: "number", description: "Max results (default 5)." },
|
|
118
|
+
minScore: { type: "number", description: "Minimum cosine similarity score (default 0.3)." },
|
|
119
|
+
},
|
|
120
|
+
required: ["query"],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "memory_forget",
|
|
125
|
+
description: "Delete memories by exact id OR by semantic query.",
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
id: { type: "string", description: "Memory ID (UUID) to delete." },
|
|
130
|
+
query: { type: "string", description: "Semantic query to match for deletion." },
|
|
131
|
+
threshold: { type: "number", description: "Similarity threshold (default 0.8) when deleting by query." },
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "memory_profile",
|
|
137
|
+
description: "Get the stored user profile summary (if any).",
|
|
138
|
+
inputSchema: { type: "object", properties: {} },
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "memory_index",
|
|
142
|
+
description: "Index a project directory by storing file contents as memories (local only). Skips common large/irrelevant folders.",
|
|
143
|
+
inputSchema: {
|
|
144
|
+
type: "object",
|
|
145
|
+
properties: {
|
|
146
|
+
directory: { type: "string", description: "Directory path to index." },
|
|
147
|
+
maxFiles: { type: "number", description: "Safety cap on number of files indexed (default 500)." },
|
|
148
|
+
maxBytesPerFile: { type: "number", description: "Max bytes per file (default 200000)." },
|
|
149
|
+
category: { type: "string", description: "Category to store under (default project-context)." },
|
|
150
|
+
tags: { type: "array", items: { type: "string" }, description: "Extra tags applied to each indexed file." },
|
|
151
|
+
},
|
|
152
|
+
required: ["directory"],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "memory_stats",
|
|
157
|
+
description: "Get memory database statistics.",
|
|
158
|
+
inputSchema: { type: "object", properties: {} },
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
164
|
+
const name = request.params.name;
|
|
165
|
+
const args = (request.params.arguments ?? {});
|
|
166
|
+
try {
|
|
167
|
+
if (name === "memory_store") {
|
|
168
|
+
const content = String(args.content ?? "").trim();
|
|
169
|
+
if (!content)
|
|
170
|
+
throw new McpError(ErrorCode.InvalidParams, "content is required");
|
|
171
|
+
const tags = asStringArray(args.tags) ?? [];
|
|
172
|
+
const category = args.category !== undefined ? String(args.category) : undefined;
|
|
173
|
+
const source = args.source !== undefined ? String(args.source) : "";
|
|
174
|
+
const embedding = await embeddings.embed(content);
|
|
175
|
+
const stored = await db.store(content, embedding, { tags, category, source });
|
|
176
|
+
db.incrementCaptureCount();
|
|
177
|
+
return textResult({
|
|
178
|
+
id: stored.entry.id,
|
|
179
|
+
isDuplicate: stored.isDuplicate,
|
|
180
|
+
updatedId: stored.updatedId,
|
|
181
|
+
created_at: stored.entry.created_at,
|
|
182
|
+
tags: stored.entry.tags,
|
|
183
|
+
category: stored.entry.category,
|
|
184
|
+
source: stored.entry.source,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (name === "memory_search") {
|
|
188
|
+
const query = String(args.query ?? "").trim();
|
|
189
|
+
if (!query)
|
|
190
|
+
throw new McpError(ErrorCode.InvalidParams, "query is required");
|
|
191
|
+
const limit = args.limit !== undefined ? Number(args.limit) : 5;
|
|
192
|
+
const minScore = args.minScore !== undefined ? Number(args.minScore) : 0.3;
|
|
193
|
+
const qvec = await embeddings.embed(query);
|
|
194
|
+
const results = await db.vectorSearch(qvec, limit, minScore);
|
|
195
|
+
return textResult({
|
|
196
|
+
query,
|
|
197
|
+
results: results.map((r) => ({
|
|
198
|
+
id: r.entry.id,
|
|
199
|
+
content: r.entry.content,
|
|
200
|
+
score: r.score,
|
|
201
|
+
created_at: r.entry.created_at,
|
|
202
|
+
source: r.entry.source,
|
|
203
|
+
tags: r.entry.tags,
|
|
204
|
+
category: r.entry.category,
|
|
205
|
+
})),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (name === "memory_forget") {
|
|
209
|
+
const id = args.id !== undefined ? String(args.id) : undefined;
|
|
210
|
+
const query = args.query !== undefined ? String(args.query).trim() : undefined;
|
|
211
|
+
const threshold = args.threshold !== undefined ? Number(args.threshold) : 0.8;
|
|
212
|
+
if (id) {
|
|
213
|
+
db.delete(id);
|
|
214
|
+
return textResult({ deleted: 1, mode: "id", id });
|
|
215
|
+
}
|
|
216
|
+
if (query) {
|
|
217
|
+
const qvec = await embeddings.embed(query);
|
|
218
|
+
const deleted = await db.deleteByQuery(qvec, threshold);
|
|
219
|
+
return textResult({ deleted, mode: "query", query, threshold });
|
|
220
|
+
}
|
|
221
|
+
throw new McpError(ErrorCode.InvalidParams, "Provide either id or query");
|
|
222
|
+
}
|
|
223
|
+
if (name === "memory_profile") {
|
|
224
|
+
const profile = db.getProfile();
|
|
225
|
+
return textResult({ profile });
|
|
226
|
+
}
|
|
227
|
+
if (name === "memory_stats") {
|
|
228
|
+
return textResult(db.stats());
|
|
229
|
+
}
|
|
230
|
+
if (name === "memory_index") {
|
|
231
|
+
const directory = String(args.directory ?? "");
|
|
232
|
+
if (!directory)
|
|
233
|
+
throw new McpError(ErrorCode.InvalidParams, "directory is required");
|
|
234
|
+
const maxFiles = args.maxFiles !== undefined ? Number(args.maxFiles) : 500;
|
|
235
|
+
const maxBytesPerFile = args.maxBytesPerFile !== undefined ? Number(args.maxBytesPerFile) : 200_000;
|
|
236
|
+
const category = args.category !== undefined ? String(args.category) : "project-context";
|
|
237
|
+
const extraTags = asStringArray(args.tags) ?? [];
|
|
238
|
+
const root = path.resolve(directory);
|
|
239
|
+
let indexed = 0;
|
|
240
|
+
let skipped = 0;
|
|
241
|
+
let errors = 0;
|
|
242
|
+
for await (const filePath of walkDir(root, { ignore: ["node_modules", ".git", "dist", "build", ".next", "out", "coverage"] })) {
|
|
243
|
+
if (indexed >= maxFiles)
|
|
244
|
+
break;
|
|
245
|
+
if (!shouldIndexFile(filePath)) {
|
|
246
|
+
skipped++;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const stat = await fs.stat(filePath);
|
|
251
|
+
if (stat.size > maxBytesPerFile) {
|
|
252
|
+
skipped++;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
const raw = await fs.readFile(filePath, "utf8");
|
|
256
|
+
const rel = path.relative(root, filePath);
|
|
257
|
+
// Keep embedding input bounded; include path header so retrieval is useful.
|
|
258
|
+
const body = raw.length > 20_000 ? raw.slice(0, 20_000) + "\n\n[truncated]" : raw;
|
|
259
|
+
const content = `File: ${rel}\n\n${body}`;
|
|
260
|
+
const emb = await embeddings.embed(content);
|
|
261
|
+
await db.store(content, emb, {
|
|
262
|
+
source: `index:${root}`,
|
|
263
|
+
category,
|
|
264
|
+
tags: ["indexed", `path:${rel}`.replaceAll("\\", "/"), ...extraTags],
|
|
265
|
+
// For indexing, be more aggressive about dedupe.
|
|
266
|
+
dedupeThreshold: 0.98,
|
|
267
|
+
});
|
|
268
|
+
indexed++;
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
errors++;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return textResult({ directory: root, indexed, skipped, errors, maxFiles, maxBytesPerFile, category, tags: extraTags });
|
|
275
|
+
}
|
|
276
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
if (err instanceof McpError)
|
|
280
|
+
throw err;
|
|
281
|
+
throw new McpError(ErrorCode.InternalError, String(err?.message ?? err));
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
// Resources
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
288
|
+
return {
|
|
289
|
+
resources: [
|
|
290
|
+
{
|
|
291
|
+
uri: "memory://profile",
|
|
292
|
+
name: "profile",
|
|
293
|
+
description: "User profile summary (if available).",
|
|
294
|
+
mimeType: "application/json",
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
uri: "memory://recent",
|
|
298
|
+
name: "recent",
|
|
299
|
+
description: "Recent memory contents (last 20).",
|
|
300
|
+
mimeType: "text/markdown",
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
uri: "memory://stats",
|
|
304
|
+
name: "stats",
|
|
305
|
+
description: "Memory database statistics.",
|
|
306
|
+
mimeType: "application/json",
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
312
|
+
const uri = request.params.uri;
|
|
313
|
+
if (uri === "memory://profile") {
|
|
314
|
+
const profile = db.getProfile();
|
|
315
|
+
return {
|
|
316
|
+
contents: [
|
|
317
|
+
{
|
|
318
|
+
uri,
|
|
319
|
+
mimeType: "application/json",
|
|
320
|
+
text: JSON.stringify({ profile }, null, 2),
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
if (uri === "memory://stats") {
|
|
326
|
+
const stats = db.stats();
|
|
327
|
+
return {
|
|
328
|
+
contents: [
|
|
329
|
+
{
|
|
330
|
+
uri,
|
|
331
|
+
mimeType: "application/json",
|
|
332
|
+
text: JSON.stringify(stats, null, 2),
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
if (uri === "memory://recent") {
|
|
338
|
+
const items = db.getAllContent(20);
|
|
339
|
+
const md = [
|
|
340
|
+
"# Recent memories",
|
|
341
|
+
"",
|
|
342
|
+
...items.map((c, i) => `## ${i + 1}\n\n${c}`),
|
|
343
|
+
].join("\n\n");
|
|
344
|
+
return {
|
|
345
|
+
contents: [
|
|
346
|
+
{
|
|
347
|
+
uri,
|
|
348
|
+
mimeType: "text/markdown",
|
|
349
|
+
text: md,
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown resource: ${uri}`);
|
|
355
|
+
});
|
|
356
|
+
// ---------------------------------------------------------------------------
|
|
357
|
+
// Transport + lifecycle
|
|
358
|
+
// ---------------------------------------------------------------------------
|
|
359
|
+
const transport = new StdioServerTransport();
|
|
360
|
+
const shutdown = async () => {
|
|
361
|
+
try {
|
|
362
|
+
await transport.close();
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
// ignore
|
|
366
|
+
}
|
|
367
|
+
try {
|
|
368
|
+
db.close();
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
// ignore
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
process.on("SIGINT", () => void shutdown());
|
|
375
|
+
process.on("SIGTERM", () => void shutdown());
|
|
376
|
+
await server.connect(transport);
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|