mem-mcp 1.3.5 → 1.3.6
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/index.js +62 -24
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -45,7 +45,7 @@ import fs from "node:fs";
|
|
|
45
45
|
|
|
46
46
|
// ============================= Config =============================
|
|
47
47
|
const MEMORY_BASE_URL = process.env.MEMORY_BASE_URL || "https://memory.node01.org";
|
|
48
|
-
const CLIENT_VERSION = "1.3.
|
|
48
|
+
const CLIENT_VERSION = "1.3.6";
|
|
49
49
|
const MEMORY_PRIVATE_KEY = process.env.MEMORY_PRIVATE_KEY;
|
|
50
50
|
|
|
51
51
|
|
|
@@ -54,6 +54,18 @@ if (!HAS_WALLET) {
|
|
|
54
54
|
console.error("NOTE: No MEMORY_PRIVATE_KEY set. Free operations (store, health, stats, sample, 30 free searches/day) will work. Paid operations (search after free tier, subscribe) will require a wallet.");
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
// ============================= Credential File Helper =============================
|
|
58
|
+
function readTokenFile() {
|
|
59
|
+
try {
|
|
60
|
+
const home = os.homedir();
|
|
61
|
+
const p = path.join(home, ".memory01_token");
|
|
62
|
+
if (fs.existsSync(p)) {
|
|
63
|
+
return fs.readFileSync(p, "utf8").trim();
|
|
64
|
+
}
|
|
65
|
+
} catch (e) {}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
57
69
|
let account = null;
|
|
58
70
|
if (HAS_WALLET) {
|
|
59
71
|
const privateKey = MEMORY_PRIVATE_KEY.startsWith("0x") ? MEMORY_PRIVATE_KEY : `0x${MEMORY_PRIVATE_KEY}`;
|
|
@@ -171,19 +183,32 @@ async function payAndRetry(endpoint, body, priceUsd = "0.01") {
|
|
|
171
183
|
}
|
|
172
184
|
|
|
173
185
|
// ============================= Free API Calls =============================
|
|
174
|
-
async function callFree(endpoint, method = "GET", body = null) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
async function callFree(endpoint, method = "GET", body = null, retries = 1) {
|
|
187
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
188
|
+
const opts = { method, headers: { "Accept": "application/json" } };
|
|
189
|
+
if (body) {
|
|
190
|
+
opts.headers["Content-Type"] = "application/json";
|
|
191
|
+
opts.body = JSON.stringify(body);
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
const response = await fetch(`${MEMORY_BASE_URL}${endpoint}`, opts);
|
|
195
|
+
const text = await response.text();
|
|
196
|
+
let data;
|
|
197
|
+
try { data = JSON.parse(text); } catch (e) {
|
|
198
|
+
if (attempt < retries) { await new Promise(r => setTimeout(r, 500)); continue; }
|
|
199
|
+
throw new Error(`Non-JSON response from ${endpoint}: ${text.substring(0, 200)}`);
|
|
200
|
+
}
|
|
201
|
+
return { data, status: response.status };
|
|
202
|
+
} catch (e) {
|
|
203
|
+
if (attempt < retries) { await new Promise(r => setTimeout(r, 500)); continue; }
|
|
204
|
+
throw e;
|
|
205
|
+
}
|
|
179
206
|
}
|
|
180
|
-
const response = await fetch(`${MEMORY_BASE_URL}${endpoint}`, opts);
|
|
181
|
-
return { data: await response.json(), status: response.status };
|
|
182
207
|
}
|
|
183
208
|
|
|
184
209
|
// ============================= MCP Server =============================
|
|
185
210
|
const server = new Server(
|
|
186
|
-
{ name: "mem-mcp", version: "1.3.
|
|
211
|
+
{ name: "mem-mcp", version: "1.3.5" },
|
|
187
212
|
{ capabilities: { tools: {} } }
|
|
188
213
|
);
|
|
189
214
|
|
|
@@ -330,10 +355,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
330
355
|
try {
|
|
331
356
|
switch (name) {
|
|
332
357
|
case "store": {
|
|
333
|
-
|
|
334
|
-
if (!
|
|
335
|
-
|
|
358
|
+
let { agentId, key, value, writeToken, sessionId, metadata, base } = args;
|
|
359
|
+
if (!writeToken) writeToken = readTokenFile();
|
|
360
|
+
if (!agentId && !writeToken) {
|
|
361
|
+
throw new McpError(ErrorCode.InvalidParams, "agentId is required on first store (no writeToken found). Pass agentId or set ~/.memory01_token.");
|
|
362
|
+
}
|
|
363
|
+
if (!key || !value) {
|
|
364
|
+
throw new McpError(ErrorCode.InvalidParams, "key and value are required");
|
|
336
365
|
}
|
|
366
|
+
if (!agentId) agentId = "agent";
|
|
337
367
|
if (key.length > 256) throw new McpError(ErrorCode.InvalidParams, "key max 256 chars");
|
|
338
368
|
const valueLimit = (args.base ? 2048 : 51200);
|
|
339
369
|
if (value.length > valueLimit) throw new McpError(ErrorCode.InvalidParams, `value max ${args.base ? '2KB (base)' : '50KB'}`);
|
|
@@ -369,10 +399,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
369
399
|
}
|
|
370
400
|
|
|
371
401
|
case "search": {
|
|
372
|
-
|
|
373
|
-
if (!
|
|
374
|
-
|
|
402
|
+
let { agentId, query, writeToken, topK = 10, sessionId, cursor, includeBase } = args;
|
|
403
|
+
if (!writeToken) writeToken = readTokenFile();
|
|
404
|
+
if (!writeToken) {
|
|
405
|
+
throw new McpError(ErrorCode.InvalidParams, "writeToken is required (or set ~/.memory01_token).");
|
|
375
406
|
}
|
|
407
|
+
if (!agentId) agentId = "agent";
|
|
376
408
|
if (query && query.length > 500) throw new McpError(ErrorCode.InvalidParams, "query max 500 chars");
|
|
377
409
|
|
|
378
410
|
const body = { agent_id: agentId, write_token: writeToken, top_k: topK, client_version: CLIENT_VERSION };
|
|
@@ -490,10 +522,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
490
522
|
}
|
|
491
523
|
|
|
492
524
|
case "bootstrap": {
|
|
493
|
-
|
|
494
|
-
if (!
|
|
495
|
-
|
|
525
|
+
let { agentId, writeToken, keys } = args;
|
|
526
|
+
if (!writeToken) writeToken = readTokenFile();
|
|
527
|
+
if (!writeToken) {
|
|
528
|
+
throw new McpError(ErrorCode.InvalidParams, "writeToken is required (or set ~/.memory01_token).");
|
|
496
529
|
}
|
|
530
|
+
if (!agentId) agentId = "agent";
|
|
497
531
|
const body = { agent_id: agentId, write_token: writeToken, client_version: CLIENT_VERSION };
|
|
498
532
|
if (keys) body.keys = keys;
|
|
499
533
|
const result = await callFree("/api/memory/bootstrap", "POST", body);
|
|
@@ -504,10 +538,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
504
538
|
}
|
|
505
539
|
|
|
506
540
|
case "get": {
|
|
507
|
-
|
|
508
|
-
if (!
|
|
509
|
-
|
|
541
|
+
let { agentId, writeToken, key } = args;
|
|
542
|
+
if (!writeToken) writeToken = readTokenFile();
|
|
543
|
+
if (!writeToken || !key) {
|
|
544
|
+
throw new McpError(ErrorCode.InvalidParams, "writeToken and key are required");
|
|
510
545
|
}
|
|
546
|
+
if (!agentId) agentId = "agent";
|
|
511
547
|
const result = await callFree("/api/memory/get", "POST", { agent_id: agentId, write_token: writeToken, key, client_version: CLIENT_VERSION });
|
|
512
548
|
if (result.status >= 400) {
|
|
513
549
|
throw new McpError(ErrorCode.InternalError, `API error: ${JSON.stringify(result.data)}`);
|
|
@@ -516,7 +552,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
516
552
|
}
|
|
517
553
|
|
|
518
554
|
case "init": {
|
|
519
|
-
|
|
555
|
+
let { agentId, writeToken: providedToken, key = "init", value = "Memory01 initialized." } = args;
|
|
556
|
+
if (!providedToken) providedToken = readTokenFile();
|
|
520
557
|
if (!agentId) {
|
|
521
558
|
throw new McpError(ErrorCode.InvalidParams, "agentId is required");
|
|
522
559
|
}
|
|
@@ -646,7 +683,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
646
683
|
}
|
|
647
684
|
|
|
648
685
|
case "regenerate_recovery": {
|
|
649
|
-
|
|
686
|
+
let { writeToken } = args;
|
|
687
|
+
if (!writeToken) writeToken = readTokenFile();
|
|
650
688
|
if (!writeToken) {
|
|
651
689
|
throw new McpError(ErrorCode.InvalidParams, "writeToken is required");
|
|
652
690
|
}
|
|
@@ -677,7 +715,7 @@ async function checkLatestVersion() {
|
|
|
677
715
|
if (!res.ok) return;
|
|
678
716
|
const data = await res.json();
|
|
679
717
|
const latest = data.version;
|
|
680
|
-
const current = "1.3.
|
|
718
|
+
const current = "1.3.5";
|
|
681
719
|
if (latest && latest !== current) {
|
|
682
720
|
console.error(`NOTE: mem-mcp ${current} is installed; latest is ${latest}. Run 'npm install -g memory-agent-mcp@latest' to update.`);
|
|
683
721
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mem-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "MCP wrapper for Memory01 agentic memory service - persistent memory for AI agents, free to store and search. Base memories, recovery codes, upsert, 50+ languages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|