@luisarg/memory-mcp 0.1.1 → 0.1.2
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/cordis.patch.yml +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/server/launcher.mjs +69 -0
- package/server/requirements.txt +4 -0
package/cordis.patch.yml
CHANGED
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
config:
|
|
11
11
|
serverName: memory
|
|
12
12
|
transport: stdio
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
# launcher.mjs (bundled with the server): `uv run` when uv is on PATH,
|
|
14
|
+
# else a pip-managed .venv (python3 -m venv + pip install -r requirements.txt)
|
|
15
|
+
command: !!js process.execPath
|
|
16
|
+
args: [!!js "(process.env.DSH_MEMORY_SERVER_DIR ?? dshHomePath('memory-vault-server')) + '/launcher.mjs'"]
|
|
15
17
|
env:
|
|
16
18
|
MEMORY_PATH: !!js process.env.DSH_MEMORY_PATH ?? dshHomePath('memory-vault')
|
|
17
19
|
UV_CACHE_DIR: /tmp/uv-cache
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;cAOa,IAAA;UAEI,MAAA;EAFJ,UAAI,EAAA,MAAA;EAEA,SAAM,EAAA,MAAA;AAKvB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;cAOa,IAAA;UAEI,MAAA;EAFJ,UAAI,EAAA,MAAA;EAEA,SAAM,EAAA,MAAA;AAKvB;AAwCgB,cAxCH,MAwCc,EAxCN,MAwCuB,CAxChB,MAwCsB,CAAA;iBAAlC,KAAA,MAAW,iBAAiB"}
|
package/dist/index.js
CHANGED
|
@@ -30,11 +30,23 @@ function ensure(target, bundled, key) {
|
|
|
30
30
|
cpSync(bundled, target, { recursive: true });
|
|
31
31
|
return true;
|
|
32
32
|
}
|
|
33
|
+
/** Copy one bundled file into `target` when missing (upgrades add files 0.1.1 → 0.1.2). */
|
|
34
|
+
function ensureFile(target, bundled, file) {
|
|
35
|
+
const dest = join(target, file);
|
|
36
|
+
if (existsSync(dest)) return false;
|
|
37
|
+
const src = join(bundled, file);
|
|
38
|
+
if (!existsSync(src)) return false;
|
|
39
|
+
mkdirSync(target, { recursive: true });
|
|
40
|
+
cpSync(src, dest);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
33
43
|
function apply(ctx, config) {
|
|
34
44
|
const serverDir = resolveUnderHome(config.serverDir, "memory-vault-server");
|
|
35
45
|
const memoryPath = resolveUnderHome(config.memoryPath, "memory-vault");
|
|
36
46
|
if (ensure(serverDir, join(packageRoot, "server"), "server.py")) console.log(`[memory-mcp] installed memory-vault-server -> ${serverDir}`);
|
|
37
47
|
if (ensure(memoryPath, join(packageRoot, "vault"), "type-registry.yaml")) console.log(`[memory-mcp] installed vault starter -> ${memoryPath}`);
|
|
48
|
+
const bundled = join(packageRoot, "server");
|
|
49
|
+
for (const file of ["launcher.mjs", "requirements.txt"]) if (ensureFile(serverDir, bundled, file)) console.log(`[memory-mcp] installed ${file} -> ${serverDir}`);
|
|
38
50
|
if (!existsSync(join(serverDir, "server.py"))) console.warn(`[memory-mcp] memory-vault-server not found at ${serverDir} and not bundled — set DSH_MEMORY_SERVER_DIR (or run \`node scripts/bundle-assets.mjs\` in a checkout)`);
|
|
39
51
|
}
|
|
40
52
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Config: Schema<Config>"],"sources":["../src/index.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, isAbsolute, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport Schema from '@deepseek-ai/schemastery'\n\nexport const name = 'memory-mcp'\n\nexport interface Config {\n memoryPath: string\n serverDir: string\n}\n\nexport const Config: Schema<Config> = Schema.object({\n memoryPath: Schema.string().default(process.env.DSH_MEMORY_PATH ?? ''),\n serverDir: Schema.string().default(process.env.DSH_MEMORY_SERVER_DIR ?? ''),\n})\n\nconst packageRoot = dirname(dirname(fileURLToPath(import.meta.url)))\n\n/** Harness home, resolved like the harness itself ($DSH_HOME, or ~/.dsh). */\nfunction dshHome(): string {\n const env = process.env.DSH_HOME?.trim()\n return env && env.length > 0 ? env : join(homedir(), '.dsh')\n}\n\n/** Absolute paths stay; empty/relative values resolve under the harness home. */\nfunction resolveUnderHome(value: string, segment: string): string {\n const v = value.trim()\n if (v.length === 0) return join(dshHome(), segment)\n return isAbsolute(v) ? v : join(dshHome(), v)\n}\n\n/** Copy the bundled dir into `target` when `key` is missing there. */\nfunction ensure(target: string, bundled: string, key: string): boolean {\n if (existsSync(join(target, key))) return false\n if (!existsSync(bundled)) return false\n mkdirSync(target, { recursive: true })\n cpSync(bundled, target, { recursive: true })\n return true\n}\n\nexport function apply(ctx: Context, config: Config) {\n const serverDir = resolveUnderHome(config.serverDir, 'memory-vault-server')\n const memoryPath = resolveUnderHome(config.memoryPath, 'memory-vault')\n\n // Self-contained install: first boot copies the bundled server and vault\n // starter under the harness home when they are missing. Env-overridden\n // paths are respected (never overwritten, never copied over).\n if (ensure(serverDir, join(packageRoot, 'server'), 'server.py')) {\n console.log(`[memory-mcp] installed memory-vault-server -> ${serverDir}`)\n }\n if (ensure(memoryPath, join(packageRoot, 'vault'), 'type-registry.yaml')) {\n console.log(`[memory-mcp] installed vault starter -> ${memoryPath}`)\n }\n if (!existsSync(join(serverDir, 'server.py'))) {\n console.warn(\n `[memory-mcp] memory-vault-server not found at ${serverDir} and not bundled — ` +\n 'set DSH_MEMORY_SERVER_DIR (or run `node scripts/bundle-assets.mjs` in a checkout)',\n )\n }\n}\n"],"mappings":";;;;;;;AAOA,MAAa,OAAO;AAOpB,MAAaA,SAAyB,OAAO,OAAO;CAClD,YAAY,OAAO,QAAQ,CAAC,QAAQ,QAAQ,IAAI,mBAAmB,GAAG;CACtE,WAAW,OAAO,QAAQ,CAAC,QAAQ,QAAQ,IAAI,yBAAyB,GAAG;CAC5E,CAAC;AAEF,MAAM,cAAc,QAAQ,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,CAAC;;AAGpE,SAAS,UAAkB;CACzB,MAAM,MAAM,QAAQ,IAAI,UAAU,MAAM;AACxC,QAAO,OAAO,IAAI,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,OAAO;;;AAI9D,SAAS,iBAAiB,OAAe,SAAyB;CAChE,MAAM,IAAI,MAAM,MAAM;AACtB,KAAI,EAAE,WAAW,EAAG,QAAO,KAAK,SAAS,EAAE,QAAQ;AACnD,QAAO,WAAW,EAAE,GAAG,IAAI,KAAK,SAAS,EAAE,EAAE;;;AAI/C,SAAS,OAAO,QAAgB,SAAiB,KAAsB;AACrE,KAAI,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAE,QAAO;AAC1C,KAAI,CAAC,WAAW,QAAQ,CAAE,QAAO;AACjC,WAAU,QAAQ,EAAE,WAAW,MAAM,CAAC;AACtC,QAAO,SAAS,QAAQ,EAAE,WAAW,MAAM,CAAC;AAC5C,QAAO;;AAGT,SAAgB,MAAM,KAAc,QAAgB;CAClD,MAAM,YAAY,iBAAiB,OAAO,WAAW,sBAAsB;CAC3E,MAAM,aAAa,iBAAiB,OAAO,YAAY,eAAe;AAKtE,KAAI,OAAO,WAAW,KAAK,aAAa,SAAS,EAAE,YAAY,CAC7D,SAAQ,IAAI,iDAAiD,YAAY;AAE3E,KAAI,OAAO,YAAY,KAAK,aAAa,QAAQ,EAAE,qBAAqB,CACtE,SAAQ,IAAI,2CAA2C,aAAa;
|
|
1
|
+
{"version":3,"file":"index.js","names":["Config: Schema<Config>"],"sources":["../src/index.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, isAbsolute, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport Schema from '@deepseek-ai/schemastery'\n\nexport const name = 'memory-mcp'\n\nexport interface Config {\n memoryPath: string\n serverDir: string\n}\n\nexport const Config: Schema<Config> = Schema.object({\n memoryPath: Schema.string().default(process.env.DSH_MEMORY_PATH ?? ''),\n serverDir: Schema.string().default(process.env.DSH_MEMORY_SERVER_DIR ?? ''),\n})\n\nconst packageRoot = dirname(dirname(fileURLToPath(import.meta.url)))\n\n/** Harness home, resolved like the harness itself ($DSH_HOME, or ~/.dsh). */\nfunction dshHome(): string {\n const env = process.env.DSH_HOME?.trim()\n return env && env.length > 0 ? env : join(homedir(), '.dsh')\n}\n\n/** Absolute paths stay; empty/relative values resolve under the harness home. */\nfunction resolveUnderHome(value: string, segment: string): string {\n const v = value.trim()\n if (v.length === 0) return join(dshHome(), segment)\n return isAbsolute(v) ? v : join(dshHome(), v)\n}\n\n/** Copy the bundled dir into `target` when `key` is missing there. */\nfunction ensure(target: string, bundled: string, key: string): boolean {\n if (existsSync(join(target, key))) return false\n if (!existsSync(bundled)) return false\n mkdirSync(target, { recursive: true })\n cpSync(bundled, target, { recursive: true })\n return true\n}\n\n/** Copy one bundled file into `target` when missing (upgrades add files 0.1.1 → 0.1.2). */\nfunction ensureFile(target: string, bundled: string, file: string): boolean {\n const dest = join(target, file)\n if (existsSync(dest)) return false\n const src = join(bundled, file)\n if (!existsSync(src)) return false\n mkdirSync(target, { recursive: true })\n cpSync(src, dest)\n return true\n}\n\nexport function apply(ctx: Context, config: Config) {\n const serverDir = resolveUnderHome(config.serverDir, 'memory-vault-server')\n const memoryPath = resolveUnderHome(config.memoryPath, 'memory-vault')\n\n // Self-contained install: first boot copies the bundled server and vault\n // starter under the harness home when they are missing. Env-overridden\n // paths are respected (never overwritten, never copied over).\n if (ensure(serverDir, join(packageRoot, 'server'), 'server.py')) {\n console.log(`[memory-mcp] installed memory-vault-server -> ${serverDir}`)\n }\n if (ensure(memoryPath, join(packageRoot, 'vault'), 'type-registry.yaml')) {\n console.log(`[memory-mcp] installed vault starter -> ${memoryPath}`)\n }\n // launcher.mjs runs the server via uv or the pip-venv fallback; upgrades of\n // existing installs (server.py already present) still need the new files.\n const bundled = join(packageRoot, 'server')\n for (const file of ['launcher.mjs', 'requirements.txt']) {\n if (ensureFile(serverDir, bundled, file)) {\n console.log(`[memory-mcp] installed ${file} -> ${serverDir}`)\n }\n }\n if (!existsSync(join(serverDir, 'server.py'))) {\n console.warn(\n `[memory-mcp] memory-vault-server not found at ${serverDir} and not bundled — ` +\n 'set DSH_MEMORY_SERVER_DIR (or run `node scripts/bundle-assets.mjs` in a checkout)',\n )\n }\n}\n"],"mappings":";;;;;;;AAOA,MAAa,OAAO;AAOpB,MAAaA,SAAyB,OAAO,OAAO;CAClD,YAAY,OAAO,QAAQ,CAAC,QAAQ,QAAQ,IAAI,mBAAmB,GAAG;CACtE,WAAW,OAAO,QAAQ,CAAC,QAAQ,QAAQ,IAAI,yBAAyB,GAAG;CAC5E,CAAC;AAEF,MAAM,cAAc,QAAQ,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,CAAC;;AAGpE,SAAS,UAAkB;CACzB,MAAM,MAAM,QAAQ,IAAI,UAAU,MAAM;AACxC,QAAO,OAAO,IAAI,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,OAAO;;;AAI9D,SAAS,iBAAiB,OAAe,SAAyB;CAChE,MAAM,IAAI,MAAM,MAAM;AACtB,KAAI,EAAE,WAAW,EAAG,QAAO,KAAK,SAAS,EAAE,QAAQ;AACnD,QAAO,WAAW,EAAE,GAAG,IAAI,KAAK,SAAS,EAAE,EAAE;;;AAI/C,SAAS,OAAO,QAAgB,SAAiB,KAAsB;AACrE,KAAI,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAE,QAAO;AAC1C,KAAI,CAAC,WAAW,QAAQ,CAAE,QAAO;AACjC,WAAU,QAAQ,EAAE,WAAW,MAAM,CAAC;AACtC,QAAO,SAAS,QAAQ,EAAE,WAAW,MAAM,CAAC;AAC5C,QAAO;;;AAIT,SAAS,WAAW,QAAgB,SAAiB,MAAuB;CAC1E,MAAM,OAAO,KAAK,QAAQ,KAAK;AAC/B,KAAI,WAAW,KAAK,CAAE,QAAO;CAC7B,MAAM,MAAM,KAAK,SAAS,KAAK;AAC/B,KAAI,CAAC,WAAW,IAAI,CAAE,QAAO;AAC7B,WAAU,QAAQ,EAAE,WAAW,MAAM,CAAC;AACtC,QAAO,KAAK,KAAK;AACjB,QAAO;;AAGT,SAAgB,MAAM,KAAc,QAAgB;CAClD,MAAM,YAAY,iBAAiB,OAAO,WAAW,sBAAsB;CAC3E,MAAM,aAAa,iBAAiB,OAAO,YAAY,eAAe;AAKtE,KAAI,OAAO,WAAW,KAAK,aAAa,SAAS,EAAE,YAAY,CAC7D,SAAQ,IAAI,iDAAiD,YAAY;AAE3E,KAAI,OAAO,YAAY,KAAK,aAAa,QAAQ,EAAE,qBAAqB,CACtE,SAAQ,IAAI,2CAA2C,aAAa;CAItE,MAAM,UAAU,KAAK,aAAa,SAAS;AAC3C,MAAK,MAAM,QAAQ,CAAC,gBAAgB,mBAAmB,CACrD,KAAI,WAAW,WAAW,SAAS,KAAK,CACtC,SAAQ,IAAI,0BAA0B,KAAK,MAAM,YAAY;AAGjE,KAAI,CAAC,WAAW,KAAK,WAAW,YAAY,CAAC,CAC3C,SAAQ,KACN,iDAAiD,UAAU,wGAE5D"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// memory-vault-server launcher — run `server.py` with uv when uv is on PATH,
|
|
2
|
+
// otherwise bootstrap a pip venv (.venv + requirements.txt) and run with that
|
|
3
|
+
// python. Used by both DSH launch points (memory-mcp cordis patch, memory-auto
|
|
4
|
+
// digest) so the fallback decision lives in exactly one place.
|
|
5
|
+
//
|
|
6
|
+
// stdout is the MCP channel of the spawned server — never print to it here.
|
|
7
|
+
// All progress/errors go to stderr.
|
|
8
|
+
//
|
|
9
|
+
// ponytail: fallback triggers only when the `uv` binary is absent, not when
|
|
10
|
+
// `uv run` fails (e.g. offline with an empty cache). If that ever matters,
|
|
11
|
+
// upgrade path: on uv run exit != 0, retry through the pip branch below.
|
|
12
|
+
|
|
13
|
+
import { spawn, spawnSync } from 'node:child_process'
|
|
14
|
+
import { existsSync } from 'node:fs'
|
|
15
|
+
import { dirname, join } from 'node:path'
|
|
16
|
+
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
17
|
+
|
|
18
|
+
const DIR = dirname(fileURLToPath(import.meta.url))
|
|
19
|
+
|
|
20
|
+
/** Pure decision: which command runs the server, given uv presence. */
|
|
21
|
+
export function resolveRunner(hasUv, dir = DIR, platform = process.platform) {
|
|
22
|
+
if (hasUv) return { command: 'uv', args: ['run', '--directory', dir, 'python', 'server.py'] }
|
|
23
|
+
const pyBin = join(dir, platform === 'win32' ? '.venv/Scripts/python.exe' : '.venv/bin/python')
|
|
24
|
+
return { command: pyBin, args: ['server.py'] }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function hasUv() {
|
|
28
|
+
return spawnSync('uv', ['--version'], { stdio: 'ignore' }).status === 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Ensure a runnable venv with the server's deps installed (pip branch only). */
|
|
32
|
+
export function ensurePipEnv(dir = DIR, platform = process.platform) {
|
|
33
|
+
const pyBin = join(dir, platform === 'win32' ? '.venv/Scripts/python.exe' : '.venv/bin/python')
|
|
34
|
+
const venvCmd = platform === 'win32' ? 'py' : 'python3'
|
|
35
|
+
if (!existsSync(pyBin)) {
|
|
36
|
+
console.error('[memory-vault-server] uv not found — creating fallback venv with ' + venvCmd)
|
|
37
|
+
// stdout is the MCP channel: keep install output off it.
|
|
38
|
+
const created = spawnSync(venvCmd, ['-m', 'venv', join(dir, '.venv')], { stdio: ['ignore', 'ignore', 'inherit'] })
|
|
39
|
+
if (created.status !== 0) {
|
|
40
|
+
console.error(`[memory-vault-server] venv creation failed (exit ${created.status}) — install uv or fix ${venvCmd}`)
|
|
41
|
+
process.exit(created.status ?? 1)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const depsOk = spawnSync(pyBin, ['-c', 'import mcp, yaml'], { stdio: 'ignore' }).status === 0
|
|
45
|
+
if (!depsOk) {
|
|
46
|
+
console.error('[memory-vault-server] fallback venv missing deps — pip install -r requirements.txt')
|
|
47
|
+
const pip = spawnSync(pyBin, ['-m', 'pip', 'install', '--quiet', '-r', join(dir, 'requirements.txt')], { stdio: ['ignore', 'ignore', 'inherit'] })
|
|
48
|
+
if (pip.status !== 0) {
|
|
49
|
+
console.error(`[memory-vault-server] pip install failed (exit ${pip.status}) — install uv, fix the network, or run the pip install manually`)
|
|
50
|
+
process.exit(pip.status ?? 1)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return pyBin
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function main() {
|
|
57
|
+
const withUv = hasUv()
|
|
58
|
+
const { command, args } = resolveRunner(withUv)
|
|
59
|
+
if (!withUv) ensurePipEnv()
|
|
60
|
+
const child = spawn(command, args, { cwd: DIR, env: process.env, stdio: 'inherit' })
|
|
61
|
+
for (const sig of ['SIGTERM', 'SIGINT']) process.on(sig, () => child.kill(sig))
|
|
62
|
+
child.on('error', (err) => {
|
|
63
|
+
console.error(`[memory-vault-server] spawn failed (${command}): ${err.message}`)
|
|
64
|
+
process.exit(1)
|
|
65
|
+
})
|
|
66
|
+
child.on('exit', (code, signal) => process.exit(code ?? (signal ? 1 : 0)))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main()
|