@vheins/local-memory-mcp 0.8.3 → 0.8.5
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.
|
@@ -35,6 +35,7 @@ var CAPABILITIES = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
// src/mcp/utils/logger.ts
|
|
38
|
+
import fs2 from "fs";
|
|
38
39
|
var LEVELS = {
|
|
39
40
|
debug: 0,
|
|
40
41
|
info: 1,
|
|
@@ -170,11 +171,31 @@ function addLogSink(sink) {
|
|
|
170
171
|
return () => sinks.delete(sink);
|
|
171
172
|
}
|
|
172
173
|
var LOG_LEVEL_VALUES = Object.keys(LEVELS);
|
|
174
|
+
function createFileSink(logDir, maxFiles = 5) {
|
|
175
|
+
fs2.mkdirSync(logDir, { recursive: true });
|
|
176
|
+
const existing = fs2.readdirSync(logDir).filter((f) => f.startsWith("mcp-") && f.endsWith(".log")).sort();
|
|
177
|
+
while (existing.length >= maxFiles) {
|
|
178
|
+
try {
|
|
179
|
+
fs2.unlinkSync(`${logDir}/${existing.shift()}`);
|
|
180
|
+
} catch {
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
184
|
+
const logFile = `${logDir}/mcp-${timestamp}.log`;
|
|
185
|
+
return (payload) => {
|
|
186
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${payload.level.toUpperCase()}] ${JSON.stringify(payload.data)}
|
|
187
|
+
`;
|
|
188
|
+
try {
|
|
189
|
+
fs2.appendFileSync(logFile, line);
|
|
190
|
+
} catch {
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
173
194
|
|
|
174
195
|
// src/mcp/storage/sqlite.ts
|
|
175
196
|
import Database from "better-sqlite3";
|
|
176
197
|
import path3 from "path";
|
|
177
|
-
import
|
|
198
|
+
import fs4 from "fs";
|
|
178
199
|
import os from "os";
|
|
179
200
|
|
|
180
201
|
// src/mcp/storage/migrations.ts
|
|
@@ -1896,7 +1917,7 @@ var SummaryEntity = class extends BaseEntity {
|
|
|
1896
1917
|
// src/mcp/storage/write-lock.ts
|
|
1897
1918
|
import lockfile from "proper-lockfile";
|
|
1898
1919
|
import path2 from "path";
|
|
1899
|
-
import
|
|
1920
|
+
import fs3 from "fs";
|
|
1900
1921
|
var LOCK_STALE_MS = 15e3;
|
|
1901
1922
|
var LOCK_RETRY_DELAY_MS = 100;
|
|
1902
1923
|
var LOCK_RETRY_COUNT = 150;
|
|
@@ -1905,9 +1926,9 @@ var WriteLock = class {
|
|
|
1905
1926
|
locked = false;
|
|
1906
1927
|
constructor(dbPath) {
|
|
1907
1928
|
this.lockTarget = dbPath;
|
|
1908
|
-
if (!
|
|
1909
|
-
|
|
1910
|
-
|
|
1929
|
+
if (!fs3.existsSync(dbPath)) {
|
|
1930
|
+
fs3.mkdirSync(path2.dirname(dbPath), { recursive: true });
|
|
1931
|
+
fs3.writeFileSync(dbPath, "");
|
|
1911
1932
|
}
|
|
1912
1933
|
}
|
|
1913
1934
|
/**
|
|
@@ -1961,11 +1982,11 @@ function resolveDbPath() {
|
|
|
1961
1982
|
if (process.env.MEMORY_DB_PATH) return process.env.MEMORY_DB_PATH;
|
|
1962
1983
|
const standardConfigDir = process.platform === "win32" ? path3.join(os.homedir(), ".local-memory-mcp") : process.platform === "darwin" ? path3.join(os.homedir(), "Library", "Application Support", "local-memory-mcp") : path3.join(os.homedir(), ".config", "local-memory-mcp");
|
|
1963
1984
|
const standardPath = path3.join(standardConfigDir, "memory.db");
|
|
1964
|
-
if (
|
|
1985
|
+
if (fs4.existsSync(standardPath)) return standardPath;
|
|
1965
1986
|
const legacyPath = path3.join(os.homedir(), ".config", "local-memory-mcp", "memory.db");
|
|
1966
|
-
if (
|
|
1987
|
+
if (fs4.existsSync(legacyPath)) return legacyPath;
|
|
1967
1988
|
const localCwdFile = path3.join(process.cwd(), "storage", "memory.db");
|
|
1968
|
-
if (
|
|
1989
|
+
if (fs4.existsSync(localCwdFile)) return localCwdFile;
|
|
1969
1990
|
return standardPath;
|
|
1970
1991
|
}
|
|
1971
1992
|
var DB_PATH = resolveDbPath();
|
|
@@ -1983,8 +2004,8 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
1983
2004
|
this.dbPathInstance = finalPath;
|
|
1984
2005
|
if (finalPath !== ":memory:") {
|
|
1985
2006
|
const dbDir = path3.dirname(finalPath);
|
|
1986
|
-
if (!
|
|
1987
|
-
|
|
2007
|
+
if (!fs4.existsSync(dbDir)) {
|
|
2008
|
+
fs4.mkdirSync(dbDir, { recursive: true });
|
|
1988
2009
|
}
|
|
1989
2010
|
}
|
|
1990
2011
|
this.db = new Database(finalPath);
|
|
@@ -2036,12 +2057,12 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
2036
2057
|
*/
|
|
2037
2058
|
_attemptRecovery(dbPath) {
|
|
2038
2059
|
const backupPath = dbPath + ".backup";
|
|
2039
|
-
if (
|
|
2060
|
+
if (fs4.existsSync(backupPath)) {
|
|
2040
2061
|
logger.warn("[SQLiteStore] Attempting recovery from backup", { backupPath });
|
|
2041
2062
|
try {
|
|
2042
2063
|
const corruptPath = `${dbPath}.corrupt_${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").slice(0, 15)}`;
|
|
2043
|
-
|
|
2044
|
-
|
|
2064
|
+
fs4.copyFileSync(dbPath, corruptPath);
|
|
2065
|
+
fs4.copyFileSync(backupPath, dbPath);
|
|
2045
2066
|
logger.warn("[SQLiteStore] Recovery successful. Corrupt file saved to", { corruptPath });
|
|
2046
2067
|
} catch (err) {
|
|
2047
2068
|
logger.error("[SQLiteStore] Recovery failed", { error: String(err) });
|
|
@@ -2059,7 +2080,7 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
2059
2080
|
try {
|
|
2060
2081
|
this.db.pragma("wal_checkpoint(PASSIVE)");
|
|
2061
2082
|
const backupPath = this.dbPathInstance + ".backup";
|
|
2062
|
-
|
|
2083
|
+
fs4.copyFileSync(this.dbPathInstance, backupPath);
|
|
2063
2084
|
} catch (err) {
|
|
2064
2085
|
logger.warn("[SQLiteStore] Backup failed", { error: String(err) });
|
|
2065
2086
|
}
|
|
@@ -3666,7 +3687,7 @@ function invalidCompletionParams(message) {
|
|
|
3666
3687
|
}
|
|
3667
3688
|
|
|
3668
3689
|
// src/mcp/prompts/loader.ts
|
|
3669
|
-
import
|
|
3690
|
+
import fs5 from "fs";
|
|
3670
3691
|
import path5 from "path";
|
|
3671
3692
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3672
3693
|
import matter from "gray-matter";
|
|
@@ -3682,8 +3703,8 @@ function findPromptDir() {
|
|
|
3682
3703
|
"./definitions"
|
|
3683
3704
|
].map((relPath) => path5.resolve(__dirname2, relPath));
|
|
3684
3705
|
for (const dir of candidates) {
|
|
3685
|
-
if (
|
|
3686
|
-
const files =
|
|
3706
|
+
if (fs5.existsSync(dir)) {
|
|
3707
|
+
const files = fs5.readdirSync(dir);
|
|
3687
3708
|
if (files.some((f) => f.endsWith(".md"))) {
|
|
3688
3709
|
return dir;
|
|
3689
3710
|
}
|
|
@@ -3693,15 +3714,15 @@ function findPromptDir() {
|
|
|
3693
3714
|
}
|
|
3694
3715
|
var PROMPT_DIR = findPromptDir();
|
|
3695
3716
|
function listPromptFiles() {
|
|
3696
|
-
if (!
|
|
3697
|
-
return
|
|
3717
|
+
if (!fs5.existsSync(PROMPT_DIR)) return [];
|
|
3718
|
+
return fs5.readdirSync(PROMPT_DIR).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, "")).sort();
|
|
3698
3719
|
}
|
|
3699
3720
|
function loadPromptFromMarkdown(name) {
|
|
3700
3721
|
const filePath = path5.join(PROMPT_DIR, `${name}.md`);
|
|
3701
|
-
if (!
|
|
3722
|
+
if (!fs5.existsSync(filePath)) {
|
|
3702
3723
|
throw new Error(`Prompt file not found: ${filePath}`);
|
|
3703
3724
|
}
|
|
3704
|
-
const fileContent =
|
|
3725
|
+
const fileContent = fs5.readFileSync(filePath, "utf-8");
|
|
3705
3726
|
const { data, content } = matter(fileContent);
|
|
3706
3727
|
return {
|
|
3707
3728
|
name: data.name || name,
|
|
@@ -3800,6 +3821,7 @@ export {
|
|
|
3800
3821
|
getLogLevel,
|
|
3801
3822
|
addLogSink,
|
|
3802
3823
|
LOG_LEVEL_VALUES,
|
|
3824
|
+
createFileSink,
|
|
3803
3825
|
normalizeRepo,
|
|
3804
3826
|
SQLiteStore,
|
|
3805
3827
|
MemoryStoreSchema,
|
package/dist/dashboard/server.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
TOOL_DEFINITIONS,
|
|
7
7
|
listResources,
|
|
8
8
|
logger
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-NQHH7CDG.js";
|
|
10
10
|
|
|
11
11
|
// src/dashboard/server.ts
|
|
12
12
|
import express from "express";
|
|
@@ -899,7 +899,7 @@ function getStaticRoot() {
|
|
|
899
899
|
}
|
|
900
900
|
var staticRoot = getStaticRoot();
|
|
901
901
|
logger.debug("Dashboard serving assets from", { staticRoot });
|
|
902
|
-
app.use(express.static(staticRoot));
|
|
902
|
+
app.use(express.static(staticRoot, { fallthrough: true }));
|
|
903
903
|
app.use((req, res, next) => {
|
|
904
904
|
if (req.path.startsWith("/api")) return next();
|
|
905
905
|
const indexPath = path3.join(staticRoot, "index.html");
|
|
@@ -936,6 +936,11 @@ app.use((req, res, next) => {
|
|
|
936
936
|
`);
|
|
937
937
|
}
|
|
938
938
|
});
|
|
939
|
+
app.use((err, req, res, _next) => {
|
|
940
|
+
if (err.status === 404) return res.status(404).end();
|
|
941
|
+
logger.error("Unhandled error", { error: err.message });
|
|
942
|
+
res.status(500).end();
|
|
943
|
+
});
|
|
939
944
|
if (process.env.DASHBOARD_ENABLE_MCP === "true") {
|
|
940
945
|
mcpClient.start().catch((e) => logger.error("MCP Client failed", { error: e.message }));
|
|
941
946
|
}
|
package/dist/mcp/server.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
addLogSink,
|
|
24
24
|
completePromptArgument,
|
|
25
25
|
completeResourceArgument,
|
|
26
|
+
createFileSink,
|
|
26
27
|
createSessionContext,
|
|
27
28
|
decodeCursor,
|
|
28
29
|
encodeCursor,
|
|
@@ -42,7 +43,7 @@ import {
|
|
|
42
43
|
setLogLevel,
|
|
43
44
|
updateSessionFromInitialize,
|
|
44
45
|
updateSessionRoots
|
|
45
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-NQHH7CDG.js";
|
|
46
47
|
|
|
47
48
|
// src/mcp/server.ts
|
|
48
49
|
import readline from "readline";
|
|
@@ -2137,6 +2138,7 @@ var RealVectorStore = class {
|
|
|
2137
2138
|
|
|
2138
2139
|
// src/mcp/server.ts
|
|
2139
2140
|
import fs2 from "fs";
|
|
2141
|
+
import path3 from "path";
|
|
2140
2142
|
process.env.MCP_SERVER = "true";
|
|
2141
2143
|
if (process.argv.includes("doctor")) {
|
|
2142
2144
|
process.stderr.write("\n\u{1F3E5} MCP Local Memory - System Diagnosis\n\n");
|
|
@@ -2168,6 +2170,7 @@ if (process.argv.includes("doctor")) {
|
|
|
2168
2170
|
}
|
|
2169
2171
|
var db = await SQLiteStore.create();
|
|
2170
2172
|
var vectors = new RealVectorStore(db);
|
|
2173
|
+
addLogSink(createFileSink(path3.dirname(db.getDbPath())));
|
|
2171
2174
|
vectors.initialize().catch((err) => {
|
|
2172
2175
|
logger.warn("[Server] Initial vector model loading failed. Will retry on first use.", { error: String(err) });
|
|
2173
2176
|
});
|