@xultrax-web/agent-memory-mcp 0.11.7 → 0.12.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/dist/index.js +47 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -615,27 +615,27 @@ export function toolDeleteMemory(args) {
|
|
|
615
615
|
const fp = memoryFilePath(name);
|
|
616
616
|
if (!existsSync(fp))
|
|
617
617
|
return `Memory "${name}" not found.`;
|
|
618
|
-
// v0.
|
|
619
|
-
//
|
|
620
|
-
//
|
|
621
|
-
//
|
|
622
|
-
// will require receipts unconditionally for destructive ops.
|
|
618
|
+
// v0.12.0 · receipt REQUIRED for delete_memory. The v0.11.x back-compat
|
|
619
|
+
// path (delete without receipt) is removed. Callers MUST first call
|
|
620
|
+
// check_action({action_type: 'deletions'}) to obtain a fresh receipt,
|
|
621
|
+
// then pass it to delete_memory as the `receipt` argument.
|
|
623
622
|
const receipt = parseReceiptArg(args.receipt);
|
|
624
|
-
if (receipt) {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
logEvent("
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
623
|
+
if (!receipt) {
|
|
624
|
+
logEvent("delete_refused_no_receipt", { name });
|
|
625
|
+
throw new Error(`delete_memory refused · receipt required (v0.12.0+). ` +
|
|
626
|
+
`Call check_action({action: 'delete memory ${name}', action_type: 'deletions'}) ` +
|
|
627
|
+
`first, then pass the issued receipt as the 'receipt' argument to delete_memory.`);
|
|
628
|
+
}
|
|
629
|
+
const v = validateReceipt(receipt, {
|
|
630
|
+
required_caveats: [{ type: "action_type", value: "deletions" }],
|
|
631
|
+
});
|
|
632
|
+
if (!v.valid) {
|
|
633
|
+
logEvent("delete_denied", { name, reason: v.reason, receipt_id: receipt.id });
|
|
634
|
+
throw new Error(`delete_memory refused · receipt invalid (${v.reason}). ` +
|
|
635
|
+
`Call check_action({action: 'delete memory ${name}', action_type: 'deletions'}) ` +
|
|
636
|
+
`to get a fresh receipt.`);
|
|
638
637
|
}
|
|
638
|
+
logEvent("delete_approved_via_receipt", { name, receipt_id: receipt.id });
|
|
639
639
|
return withLock(() => {
|
|
640
640
|
ensureTrash();
|
|
641
641
|
// Trash filename: <unix-ms>-<name>.md so restore can pick the
|
|
@@ -644,12 +644,9 @@ export function toolDeleteMemory(args) {
|
|
|
644
644
|
const trashPath = join(TRASH_DIR, `${ts}-${name}.md`);
|
|
645
645
|
renameSync(fp, trashPath);
|
|
646
646
|
removeIndexEntryUnlocked(name);
|
|
647
|
-
logEvent("delete", { name, trash: `${ts}-${name}.md`, gated:
|
|
647
|
+
logEvent("delete", { name, trash: `${ts}-${name}.md`, gated: true });
|
|
648
648
|
log("debug", "delete_memory", { name });
|
|
649
|
-
|
|
650
|
-
? ` (gated by receipt ${receipt.id})`
|
|
651
|
-
: " (no receipt · v0.11.3 back-compat path)";
|
|
652
|
-
return `Moved "${name}" to trash${gateMsg}. Restore with: agent-memory restore ${name}`;
|
|
649
|
+
return `Moved "${name}" to trash (gated by receipt ${receipt.id}). Restore with: agent-memory restore ${name}`;
|
|
653
650
|
});
|
|
654
651
|
}
|
|
655
652
|
function toolRestoreMemory(args) {
|
|
@@ -1782,7 +1779,14 @@ function recentDenials() {
|
|
|
1782
1779
|
}));
|
|
1783
1780
|
}
|
|
1784
1781
|
function recentUnreceiptedDeletes() {
|
|
1785
|
-
|
|
1782
|
+
// v0.11.x emitted "delete_without_receipt" when an unreceipted delete
|
|
1783
|
+
// succeeded. v0.12.0 emits "delete_refused_no_receipt" when refusing.
|
|
1784
|
+
// We surface BOTH event types so an audit run against pre-v0.12 logs
|
|
1785
|
+
// still reports historical unreceipted deletes correctly.
|
|
1786
|
+
const records = [
|
|
1787
|
+
...readEventLog({ tail: AUDIT_EVENT_TAIL, action: "delete_without_receipt" }),
|
|
1788
|
+
...readEventLog({ tail: AUDIT_EVENT_TAIL, action: "delete_refused_no_receipt" }),
|
|
1789
|
+
];
|
|
1786
1790
|
return records.map((r) => ({
|
|
1787
1791
|
ts: String(r.ts),
|
|
1788
1792
|
name: String(r.name ?? ""),
|
|
@@ -2188,7 +2192,7 @@ function actionColor(action) {
|
|
|
2188
2192
|
// -------------------------------------------------------------
|
|
2189
2193
|
// Server wiring
|
|
2190
2194
|
// -------------------------------------------------------------
|
|
2191
|
-
const server = new Server({ name: "agent-memory", version: "0.
|
|
2195
|
+
const server = new Server({ name: "agent-memory", version: "0.12.0" }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
|
|
2192
2196
|
// -------------------------------------------------------------
|
|
2193
2197
|
// Resource URI scheme
|
|
2194
2198
|
// -------------------------------------------------------------
|
|
@@ -2512,18 +2516,18 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
2512
2516
|
{
|
|
2513
2517
|
name: "delete_memory",
|
|
2514
2518
|
description: "Move a memory to .trash/ (soft delete). The file is removed from the index but recoverable via restore_memory until you manually empty .trash/. " +
|
|
2515
|
-
"v0.
|
|
2519
|
+
"v0.12.0+ · receipt REQUIRED. Caller MUST first call check_action({action: 'delete memory <name>', action_type: 'deletions'}) to obtain a fresh Compliance Receipt, then pass it to this tool as `receipt`. " +
|
|
2516
2520
|
"Receipts must carry the caveat {type: 'action_type', value: 'deletions'} or the delete refuses. " +
|
|
2517
|
-
"
|
|
2521
|
+
"Migration from v0.11.x: previously unreceipted deletes were accepted with a warning · now they throw. Add a check_action call before each delete_memory call.",
|
|
2518
2522
|
inputSchema: {
|
|
2519
2523
|
type: "object",
|
|
2520
2524
|
properties: {
|
|
2521
2525
|
name: { type: "string", description: "The memory's name slug" },
|
|
2522
2526
|
receipt: {
|
|
2523
|
-
description: "
|
|
2527
|
+
description: "REQUIRED · Compliance Receipt (object or JSON string) from check_action with action_type=deletions. Without this, the delete is refused.",
|
|
2524
2528
|
},
|
|
2525
2529
|
},
|
|
2526
|
-
required: ["name"],
|
|
2530
|
+
required: ["name", "receipt"],
|
|
2527
2531
|
},
|
|
2528
2532
|
},
|
|
2529
2533
|
{
|
|
@@ -2986,7 +2990,19 @@ async function cliMain(command, rest) {
|
|
|
2986
2990
|
const name = positional[0];
|
|
2987
2991
|
if (!name)
|
|
2988
2992
|
throw new Error("Usage: agent-memory delete <name>");
|
|
2989
|
-
|
|
2993
|
+
// v0.12.0+ · delete_memory requires a Compliance Receipt. The CLI
|
|
2994
|
+
// is the trusted operator path (a human is running the command,
|
|
2995
|
+
// not an AI agent), so we auto-issue a CLI-scoped receipt rather
|
|
2996
|
+
// than make the operator chain `check-action` then paste JSON.
|
|
2997
|
+
// MCP callers (AI agents) still must go through check_action
|
|
2998
|
+
// explicitly — this short-circuit only fires from the CLI binary.
|
|
2999
|
+
const receipt = issueReceipt({
|
|
3000
|
+
caveats: [
|
|
3001
|
+
{ type: "action_type", value: "deletions" },
|
|
3002
|
+
{ type: "issued_by", value: "cli" },
|
|
3003
|
+
],
|
|
3004
|
+
});
|
|
3005
|
+
process.stdout.write(toolDeleteMemory({ name, receipt: JSON.stringify(receipt) }) + "\n");
|
|
2990
3006
|
return 0;
|
|
2991
3007
|
}
|
|
2992
3008
|
case "restore": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xultrax-web/agent-memory-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"mcpName": "io.github.xultrax-web/agent-memory-mcp",
|
|
5
5
|
"description": "Codify how you work. Every AI tool obeys. Markdown rules + cross-tool companion files (AGENTS.md/CLAUDE.md/.cursor/rules/.gemini) + Compliance Receipts for protocol-level enforcement of destructive ops. Reference implementation of CRP 1.0. Works on every MCP client (no Sampling required).",
|
|
6
6
|
"type": "module",
|