@hasna/mementos 0.4.4 → 0.4.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.
package/dist/mcp/index.js CHANGED
@@ -6129,6 +6129,21 @@ ${formatMemory(best.memory)}`
6129
6129
  return { content: [{ type: "text", text: formatError(e) }], isError: true };
6130
6130
  }
6131
6131
  });
6132
+ server.tool("memory_get", "Get a single memory by ID.", {
6133
+ id: exports_external.string()
6134
+ }, async (args) => {
6135
+ try {
6136
+ const id = resolveId(args.id);
6137
+ const memory = getMemory(id);
6138
+ if (!memory) {
6139
+ return { content: [{ type: "text", text: `Memory not found: ${args.id}` }] };
6140
+ }
6141
+ touchMemory(memory.id);
6142
+ return { content: [{ type: "text", text: formatMemory(memory) }] };
6143
+ } catch (e) {
6144
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
6145
+ }
6146
+ });
6132
6147
  server.tool("memory_list", "List memories. Default: compact lines. full=true for complete JSON objects.", {
6133
6148
  scope: exports_external.enum(["global", "shared", "private"]).optional(),
6134
6149
  category: exports_external.enum(["preference", "fact", "knowledge", "history"]).optional(),
@@ -6350,6 +6365,7 @@ server.tool("memory_inject", "Get memory context for system prompt injection. Se
6350
6365
  max_tokens: exports_external.coerce.number().optional(),
6351
6366
  categories: exports_external.array(exports_external.enum(["preference", "fact", "knowledge", "history"])).optional(),
6352
6367
  min_importance: exports_external.coerce.number().optional(),
6368
+ format: exports_external.enum(["xml", "markdown", "compact", "json"]).optional(),
6353
6369
  raw: exports_external.boolean().optional()
6354
6370
  }, async (args) => {
6355
6371
  try {
@@ -6403,8 +6419,16 @@ server.tool("memory_inject", "Get memory context for system prompt injection. Se
6403
6419
  const charBudget = maxTokens * 4;
6404
6420
  const lines = [];
6405
6421
  let totalChars = 0;
6422
+ const fmt = args.format ?? (args.raw ? "compact" : "xml");
6406
6423
  for (const m of unique) {
6407
- const line = `- [${m.scope}/${m.category}] ${m.key}: ${m.value}`;
6424
+ let line;
6425
+ if (fmt === "compact") {
6426
+ line = `${m.key}: ${m.value}`;
6427
+ } else if (fmt === "json") {
6428
+ line = JSON.stringify({ key: m.key, value: m.value, scope: m.scope, category: m.category, importance: m.importance });
6429
+ } else {
6430
+ line = `- [${m.scope}/${m.category}] ${m.key}: ${m.value}`;
6431
+ }
6408
6432
  if (totalChars + line.length > charBudget)
6409
6433
  break;
6410
6434
  lines.push(line);
@@ -6414,11 +6438,23 @@ server.tool("memory_inject", "Get memory context for system prompt injection. Se
6414
6438
  if (lines.length === 0) {
6415
6439
  return { content: [{ type: "text", text: "No relevant memories found for injection." }] };
6416
6440
  }
6417
- const context = args.raw ? lines.join(`
6418
- `) : `<agent-memories>
6441
+ let context;
6442
+ if (fmt === "compact") {
6443
+ context = lines.join(`
6444
+ `);
6445
+ } else if (fmt === "json") {
6446
+ context = `[${lines.join(",")}]`;
6447
+ } else if (fmt === "markdown") {
6448
+ context = `## Agent Memories
6449
+
6450
+ ${lines.join(`
6451
+ `)}`;
6452
+ } else {
6453
+ context = `<agent-memories>
6419
6454
  ${lines.join(`
6420
6455
  `)}
6421
6456
  </agent-memories>`;
6457
+ }
6422
6458
  return { content: [{ type: "text", text: context }] };
6423
6459
  } catch (e) {
6424
6460
  return { content: [{ type: "text", text: formatError(e) }], isError: true };
@@ -6566,6 +6602,29 @@ ${lines.join(`
6566
6602
  return { content: [{ type: "text", text: formatError(e) }], isError: true };
6567
6603
  }
6568
6604
  });
6605
+ server.tool("get_project", "Get a project by ID, path, or name.", {
6606
+ id: exports_external.string()
6607
+ }, async (args) => {
6608
+ try {
6609
+ const project = getProject(args.id);
6610
+ if (!project) {
6611
+ return { content: [{ type: "text", text: `Project not found: ${args.id}` }] };
6612
+ }
6613
+ return {
6614
+ content: [{
6615
+ type: "text",
6616
+ text: `Project:
6617
+ ID: ${project.id}
6618
+ Name: ${project.name}
6619
+ Path: ${project.path}
6620
+ Description: ${project.description || "-"}
6621
+ Created: ${project.created_at}`
6622
+ }]
6623
+ };
6624
+ } catch (e) {
6625
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
6626
+ }
6627
+ });
6569
6628
  server.tool("bulk_forget", "Delete multiple memories by IDs", {
6570
6629
  ids: exports_external.array(exports_external.string())
6571
6630
  }, async (args) => {
@@ -6890,6 +6949,14 @@ var FULL_SCHEMAS = {
6890
6949
  },
6891
6950
  example: '{"key":"preferred-language","value":"TypeScript","scope":"global","importance":8,"tags":["language","preference"]}'
6892
6951
  },
6952
+ memory_get: {
6953
+ description: "Get a single memory by ID (partial IDs resolved).",
6954
+ category: "memory",
6955
+ params: {
6956
+ id: { type: "string", description: "Memory ID (full or partial)", required: true }
6957
+ },
6958
+ example: '{"id":"abc12345"}'
6959
+ },
6893
6960
  memory_recall: {
6894
6961
  description: "Recall a memory by exact key. Falls back to fuzzy search if no exact match.",
6895
6962
  category: "memory",
@@ -7003,9 +7070,10 @@ var FULL_SCHEMAS = {
7003
7070
  max_tokens: { type: "number", description: "Approximate token budget (default 500)" },
7004
7071
  categories: { type: "array", description: "Categories to include (default: preference, fact, knowledge)", items: { type: "string", enum: ["preference", "fact", "knowledge", "history"] } },
7005
7072
  min_importance: { type: "number", description: "Minimum importance (default 3)" },
7006
- raw: { type: "boolean", description: "true=plain lines only, false=wrapped in <agent-memories> tags" }
7073
+ format: { type: "string", description: "Output format: xml (default, <agent-memories>), compact (key: value, ~60% smaller), markdown, json", enum: ["xml", "compact", "markdown", "json"] },
7074
+ raw: { type: "boolean", description: "Deprecated: use format=compact instead. true=plain lines only" }
7007
7075
  },
7008
- example: '{"project_id":"proj-uuid","max_tokens":300,"min_importance":5}'
7076
+ example: '{"project_id":"proj-uuid","max_tokens":300,"min_importance":5,"format":"compact"}'
7009
7077
  },
7010
7078
  memory_context: {
7011
7079
  description: "Get active memories for the current context (agent/project/scope).",
@@ -7080,6 +7148,14 @@ var FULL_SCHEMAS = {
7080
7148
  params: {},
7081
7149
  example: "{}"
7082
7150
  },
7151
+ get_project: {
7152
+ description: "Get a project by ID, path, or name.",
7153
+ category: "project",
7154
+ params: {
7155
+ id: { type: "string", description: "Project ID, path, or name", required: true }
7156
+ },
7157
+ example: '{"id":"open-mementos"}'
7158
+ },
7083
7159
  bulk_forget: {
7084
7160
  description: "Delete multiple memories by IDs in one call.",
7085
7161
  category: "bulk",
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AA87BH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoG9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAy+BH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoG9C"}
@@ -2179,6 +2179,45 @@ addRoute("POST", "/api/memories/import", async (req) => {
2179
2179
  }
2180
2180
  return json({ imported, errors, total: memoriesArr.length }, 201);
2181
2181
  });
2182
+ addRoute("POST", "/api/memories/bulk-forget", async (req) => {
2183
+ const body = await readJson(req);
2184
+ if (!body || !Array.isArray(body["ids"])) {
2185
+ return errorResponse("Missing required field: ids (array)", 400);
2186
+ }
2187
+ const ids = body["ids"];
2188
+ let deleted = 0;
2189
+ for (const id of ids) {
2190
+ try {
2191
+ if (deleteMemory(id))
2192
+ deleted++;
2193
+ } catch {}
2194
+ }
2195
+ return json({ deleted, total: ids.length });
2196
+ });
2197
+ addRoute("POST", "/api/memories/bulk-update", async (req) => {
2198
+ const body = await readJson(req);
2199
+ if (!body || !Array.isArray(body["ids"])) {
2200
+ return errorResponse("Missing required fields: ids (array)", 400);
2201
+ }
2202
+ const ids = body["ids"];
2203
+ const { ids: _ids, ...fields } = body;
2204
+ let updated = 0;
2205
+ const errors = [];
2206
+ for (const id of ids) {
2207
+ try {
2208
+ const memory = getMemory(id);
2209
+ if (memory) {
2210
+ updateMemory(id, { ...fields, version: memory.version });
2211
+ updated++;
2212
+ } else {
2213
+ errors.push(`Memory not found: ${id}`);
2214
+ }
2215
+ } catch (e) {
2216
+ errors.push(`Failed ${id}: ${e instanceof Error ? e.message : String(e)}`);
2217
+ }
2218
+ }
2219
+ return json({ updated, errors, total: ids.length });
2220
+ });
2182
2221
  addRoute("POST", "/api/memories/clean", () => {
2183
2222
  const cleaned = cleanExpiredMemories();
2184
2223
  return json({ cleaned });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",