ziiagentmemory 0.1.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/.env.example +175 -0
- package/AGENTS.md +124 -0
- package/LICENSE +190 -0
- package/README.md +1546 -0
- package/dist/cli.d.mts +5 -0
- package/dist/cli.d.mts.map +1 -0
- package/dist/cli.mjs +2859 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/config-ChC9EtgV.mjs +259 -0
- package/dist/config-ChC9EtgV.mjs.map +1 -0
- package/dist/connect-JnsJXc68.mjs +1075 -0
- package/dist/connect-JnsJXc68.mjs.map +1 -0
- package/dist/hooks/notification.d.mts +1 -0
- package/dist/hooks/notification.mjs +74 -0
- package/dist/hooks/notification.mjs.map +1 -0
- package/dist/hooks/post-commit.d.mts +1 -0
- package/dist/hooks/post-commit.mjs +101 -0
- package/dist/hooks/post-commit.mjs.map +1 -0
- package/dist/hooks/post-tool-failure.d.mts +1 -0
- package/dist/hooks/post-tool-failure.mjs +75 -0
- package/dist/hooks/post-tool-failure.mjs.map +1 -0
- package/dist/hooks/post-tool-use.d.mts +1 -0
- package/dist/hooks/post-tool-use.mjs +120 -0
- package/dist/hooks/post-tool-use.mjs.map +1 -0
- package/dist/hooks/pre-compact.d.mts +1 -0
- package/dist/hooks/pre-compact.mjs +78 -0
- package/dist/hooks/pre-compact.mjs.map +1 -0
- package/dist/hooks/pre-tool-use.d.mts +1 -0
- package/dist/hooks/pre-tool-use.mjs +84 -0
- package/dist/hooks/pre-tool-use.mjs.map +1 -0
- package/dist/hooks/prompt-submit.d.mts +1 -0
- package/dist/hooks/prompt-submit.mjs +67 -0
- package/dist/hooks/prompt-submit.mjs.map +1 -0
- package/dist/hooks/session-end.d.mts +1 -0
- package/dist/hooks/session-end.mjs +60 -0
- package/dist/hooks/session-end.mjs.map +1 -0
- package/dist/hooks/session-start.d.mts +1 -0
- package/dist/hooks/session-start.mjs +85 -0
- package/dist/hooks/session-start.mjs.map +1 -0
- package/dist/hooks/stop.d.mts +1 -0
- package/dist/hooks/stop.mjs +44 -0
- package/dist/hooks/stop.mjs.map +1 -0
- package/dist/hooks/subagent-start.d.mts +1 -0
- package/dist/hooks/subagent-start.mjs +73 -0
- package/dist/hooks/subagent-start.mjs.map +1 -0
- package/dist/hooks/subagent-stop.d.mts +1 -0
- package/dist/hooks/subagent-stop.mjs +74 -0
- package/dist/hooks/subagent-stop.mjs.map +1 -0
- package/dist/hooks/task-completed.d.mts +1 -0
- package/dist/hooks/task-completed.mjs +73 -0
- package/dist/hooks/task-completed.mjs.map +1 -0
- package/dist/image-refs-BKLmp_sD.mjs +34 -0
- package/dist/image-refs-BKLmp_sD.mjs.map +1 -0
- package/dist/image-refs-C2YU7BIm.mjs +34 -0
- package/dist/image-refs-C2YU7BIm.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +22324 -0
- package/dist/index.mjs.map +1 -0
- package/dist/keyed-mutex-DTHtcZrt.mjs +88 -0
- package/dist/keyed-mutex-DTHtcZrt.mjs.map +1 -0
- package/dist/logger-BEB7pCI9.mjs +43 -0
- package/dist/logger-BEB7pCI9.mjs.map +1 -0
- package/dist/schema-CNiCWzV9.mjs +78 -0
- package/dist/schema-CNiCWzV9.mjs.map +1 -0
- package/dist/src-Cr3pH_uH.mjs +20745 -0
- package/dist/src-Cr3pH_uH.mjs.map +1 -0
- package/dist/standalone-C6KzNkt5.mjs +700 -0
- package/dist/standalone-C6KzNkt5.mjs.map +1 -0
- package/dist/standalone.d.mts +25 -0
- package/dist/standalone.d.mts.map +1 -0
- package/dist/standalone.mjs +1867 -0
- package/dist/standalone.mjs.map +1 -0
- package/dist/tools-registry-DCt2KAWA.mjs +1145 -0
- package/dist/tools-registry-DCt2KAWA.mjs.map +1 -0
- package/docker-compose.yml +47 -0
- package/iii-config.docker.yaml +53 -0
- package/iii-config.yaml +61 -0
- package/package.json +99 -0
- package/plugin/.claude-plugin/plugin.json +13 -0
- package/plugin/.codex-plugin/plugin.json +15 -0
- package/plugin/.mcp.copilot.json +15 -0
- package/plugin/.mcp.json +13 -0
- package/plugin/hooks/hooks.codex.json +67 -0
- package/plugin/hooks/hooks.copilot.json +72 -0
- package/plugin/hooks/hooks.json +125 -0
- package/plugin/opencode/README.md +229 -0
- package/plugin/opencode/agentmemory-capture.ts +687 -0
- package/plugin/opencode/commands/recall.md +19 -0
- package/plugin/opencode/commands/remember.md +19 -0
- package/plugin/opencode/plugin.json +12 -0
- package/plugin/plugin.json +15 -0
- package/plugin/scripts/diagnostics.mjs +551 -0
- package/plugin/scripts/notification.d.mts +1 -0
- package/plugin/scripts/notification.mjs +74 -0
- package/plugin/scripts/notification.mjs.map +1 -0
- package/plugin/scripts/post-commit.d.mts +1 -0
- package/plugin/scripts/post-commit.mjs +101 -0
- package/plugin/scripts/post-commit.mjs.map +1 -0
- package/plugin/scripts/post-tool-failure.d.mts +1 -0
- package/plugin/scripts/post-tool-failure.mjs +75 -0
- package/plugin/scripts/post-tool-failure.mjs.map +1 -0
- package/plugin/scripts/post-tool-use.d.mts +1 -0
- package/plugin/scripts/post-tool-use.mjs +120 -0
- package/plugin/scripts/post-tool-use.mjs.map +1 -0
- package/plugin/scripts/pre-compact.d.mts +1 -0
- package/plugin/scripts/pre-compact.mjs +78 -0
- package/plugin/scripts/pre-compact.mjs.map +1 -0
- package/plugin/scripts/pre-tool-use.d.mts +1 -0
- package/plugin/scripts/pre-tool-use.mjs +84 -0
- package/plugin/scripts/pre-tool-use.mjs.map +1 -0
- package/plugin/scripts/prompt-submit.d.mts +1 -0
- package/plugin/scripts/prompt-submit.mjs +67 -0
- package/plugin/scripts/prompt-submit.mjs.map +1 -0
- package/plugin/scripts/session-end.d.mts +1 -0
- package/plugin/scripts/session-end.mjs +60 -0
- package/plugin/scripts/session-end.mjs.map +1 -0
- package/plugin/scripts/session-start.d.mts +1 -0
- package/plugin/scripts/session-start.mjs +85 -0
- package/plugin/scripts/session-start.mjs.map +1 -0
- package/plugin/scripts/stop.d.mts +1 -0
- package/plugin/scripts/stop.mjs +44 -0
- package/plugin/scripts/stop.mjs.map +1 -0
- package/plugin/scripts/subagent-start.d.mts +1 -0
- package/plugin/scripts/subagent-start.mjs +73 -0
- package/plugin/scripts/subagent-start.mjs.map +1 -0
- package/plugin/scripts/subagent-stop.d.mts +1 -0
- package/plugin/scripts/subagent-stop.mjs +74 -0
- package/plugin/scripts/subagent-stop.mjs.map +1 -0
- package/plugin/scripts/task-completed.d.mts +1 -0
- package/plugin/scripts/task-completed.mjs +73 -0
- package/plugin/scripts/task-completed.mjs.map +1 -0
- package/plugin/skills/_shared/TROUBLESHOOTING.md +38 -0
- package/plugin/skills/agentmemory-agents/REFERENCE.md +28 -0
- package/plugin/skills/agentmemory-agents/SKILL.md +34 -0
- package/plugin/skills/agentmemory-architecture/SKILL.md +33 -0
- package/plugin/skills/agentmemory-config/REFERENCE.md +42 -0
- package/plugin/skills/agentmemory-config/SKILL.md +37 -0
- package/plugin/skills/agentmemory-hooks/REFERENCE.md +20 -0
- package/plugin/skills/agentmemory-hooks/SKILL.md +39 -0
- package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +65 -0
- package/plugin/skills/agentmemory-mcp-tools/SKILL.md +39 -0
- package/plugin/skills/agentmemory-rest-api/REFERENCE.md +129 -0
- package/plugin/skills/agentmemory-rest-api/SKILL.md +43 -0
- package/plugin/skills/commit-context/EXAMPLES.md +71 -0
- package/plugin/skills/commit-context/SKILL.md +64 -0
- package/plugin/skills/commit-history/EXAMPLES.md +71 -0
- package/plugin/skills/commit-history/SKILL.md +62 -0
- package/plugin/skills/forget/EXAMPLES.md +75 -0
- package/plugin/skills/forget/SKILL.md +66 -0
- package/plugin/skills/handoff/EXAMPLES.md +56 -0
- package/plugin/skills/handoff/SKILL.md +68 -0
- package/plugin/skills/recall/EXAMPLES.md +74 -0
- package/plugin/skills/recall/SKILL.md +60 -0
- package/plugin/skills/recap/EXAMPLES.md +60 -0
- package/plugin/skills/recap/SKILL.md +63 -0
- package/plugin/skills/remember/EXAMPLES.md +67 -0
- package/plugin/skills/remember/SKILL.md +61 -0
- package/plugin/skills/session-history/EXAMPLES.md +59 -0
- package/plugin/skills/session-history/SKILL.md +61 -0
- package/plugin/skills/write-agentmemory-skill/SKILL.md +40 -0
|
@@ -0,0 +1,700 @@
|
|
|
1
|
+
import { i as generateId } from "./schema-CNiCWzV9.mjs";
|
|
2
|
+
import { i as VERSION, n as getAllTools } from "./tools-registry-DCt2KAWA.mjs";
|
|
3
|
+
import { s as getStandalonePersistPath } from "./config-ChC9EtgV.mjs";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { dirname } from "node:path";
|
|
6
|
+
//#region src/mcp/in-memory-kv.ts
|
|
7
|
+
var InMemoryKV = class {
|
|
8
|
+
store = /* @__PURE__ */ new Map();
|
|
9
|
+
constructor(persistPath) {
|
|
10
|
+
this.persistPath = persistPath;
|
|
11
|
+
if (persistPath && existsSync(persistPath)) try {
|
|
12
|
+
const data = JSON.parse(readFileSync(persistPath, "utf-8"));
|
|
13
|
+
for (const [scope, entries] of Object.entries(data)) {
|
|
14
|
+
const map = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const [key, value] of Object.entries(entries)) map.set(key, value);
|
|
16
|
+
this.store.set(scope, map);
|
|
17
|
+
}
|
|
18
|
+
} catch {}
|
|
19
|
+
}
|
|
20
|
+
async get(scope, key) {
|
|
21
|
+
return this.store.get(scope)?.get(key) ?? null;
|
|
22
|
+
}
|
|
23
|
+
async set(scope, key, data) {
|
|
24
|
+
if (!this.store.has(scope)) this.store.set(scope, /* @__PURE__ */ new Map());
|
|
25
|
+
this.store.get(scope).set(key, data);
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
async delete(scope, key) {
|
|
29
|
+
this.store.get(scope)?.delete(key);
|
|
30
|
+
}
|
|
31
|
+
async list(scope) {
|
|
32
|
+
const entries = this.store.get(scope);
|
|
33
|
+
return entries ? Array.from(entries.values()) : [];
|
|
34
|
+
}
|
|
35
|
+
persist() {
|
|
36
|
+
if (!this.persistPath) return;
|
|
37
|
+
try {
|
|
38
|
+
const dir = dirname(this.persistPath);
|
|
39
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
40
|
+
const data = {};
|
|
41
|
+
for (const [scope, entries] of this.store) data[scope] = Object.fromEntries(entries);
|
|
42
|
+
writeFileSync(this.persistPath, JSON.stringify(data), "utf-8");
|
|
43
|
+
} catch (err) {
|
|
44
|
+
process.stderr.write(`[@agentmemory/mcp] Persist failed: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/mcp/transport.ts
|
|
50
|
+
function isNotification(req) {
|
|
51
|
+
return req.id === void 0 || req.id === null;
|
|
52
|
+
}
|
|
53
|
+
function isValidId(id) {
|
|
54
|
+
return id === void 0 || id === null || typeof id === "string" || typeof id === "number";
|
|
55
|
+
}
|
|
56
|
+
async function processLine(line, handler, writeOut, writeErr = (msg) => process.stderr.write(msg)) {
|
|
57
|
+
const trimmed = line.trim();
|
|
58
|
+
if (!trimmed) return;
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = JSON.parse(trimmed);
|
|
62
|
+
} catch {
|
|
63
|
+
writeOut({
|
|
64
|
+
jsonrpc: "2.0",
|
|
65
|
+
id: null,
|
|
66
|
+
error: {
|
|
67
|
+
code: -32700,
|
|
68
|
+
message: "Parse error"
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const request = parsed;
|
|
74
|
+
const rawId = request?.id;
|
|
75
|
+
if (!request || typeof request !== "object" || request.jsonrpc !== "2.0" || typeof request.method !== "string") {
|
|
76
|
+
if (typeof rawId === "string" || typeof rawId === "number") writeOut({
|
|
77
|
+
jsonrpc: "2.0",
|
|
78
|
+
id: rawId,
|
|
79
|
+
error: {
|
|
80
|
+
code: -32600,
|
|
81
|
+
message: "Invalid Request"
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!isValidId(rawId)) {
|
|
87
|
+
writeOut({
|
|
88
|
+
jsonrpc: "2.0",
|
|
89
|
+
id: null,
|
|
90
|
+
error: {
|
|
91
|
+
code: -32600,
|
|
92
|
+
message: "Invalid Request: id must be string, number, or null"
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const notification = isNotification(request);
|
|
98
|
+
try {
|
|
99
|
+
const result = await handler(request.method, request.params || {});
|
|
100
|
+
if (notification) return;
|
|
101
|
+
writeOut({
|
|
102
|
+
jsonrpc: "2.0",
|
|
103
|
+
id: request.id,
|
|
104
|
+
result
|
|
105
|
+
});
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (notification) {
|
|
108
|
+
writeErr(`[mcp-transport] notification handler error for ${request.method}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
writeOut({
|
|
112
|
+
jsonrpc: "2.0",
|
|
113
|
+
id: request.id,
|
|
114
|
+
error: {
|
|
115
|
+
code: -32603,
|
|
116
|
+
message: err instanceof Error ? err.message : String(err)
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function findHeaderEnd(buffer) {
|
|
122
|
+
const crlf = buffer.indexOf("\r\n\r\n");
|
|
123
|
+
const lf = buffer.indexOf("\n\n");
|
|
124
|
+
if (crlf === -1 && lf === -1) return null;
|
|
125
|
+
if (crlf !== -1 && (lf === -1 || crlf <= lf)) return {
|
|
126
|
+
headerEnd: crlf,
|
|
127
|
+
bodyStart: crlf + 4
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
headerEnd: lf,
|
|
131
|
+
bodyStart: lf + 2
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function parseContentLength(header) {
|
|
135
|
+
for (const line of header.split(/\r?\n/)) {
|
|
136
|
+
const match = line.match(/^content-length:\s*(\d+)\s*$/i);
|
|
137
|
+
if (match) return Number(match[1]);
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
function formatResponse(response, framed) {
|
|
142
|
+
const body = JSON.stringify(response);
|
|
143
|
+
if (!framed) return `${body}\n`;
|
|
144
|
+
const bytes = Buffer.from(body, "utf8");
|
|
145
|
+
return [Buffer.from(`Content-Length: ${bytes.length}\r\n\r\n`, "ascii"), bytes];
|
|
146
|
+
}
|
|
147
|
+
function createMessageParser(onMessage, writeErr = (msg) => process.stderr.write(msg)) {
|
|
148
|
+
let buffer = Buffer.alloc(0);
|
|
149
|
+
let framed = false;
|
|
150
|
+
function processBuffer() {
|
|
151
|
+
while (buffer.length > 0) {
|
|
152
|
+
if (buffer[0] === 10 || buffer[0] === 13) {
|
|
153
|
+
buffer = buffer.subarray(1);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const preview = buffer.toString("ascii", 0, Math.min(buffer.length, 32));
|
|
157
|
+
if (/^content-length:/i.test(preview)) {
|
|
158
|
+
const header = findHeaderEnd(buffer);
|
|
159
|
+
if (!header) return;
|
|
160
|
+
const contentLength = parseContentLength(buffer.subarray(0, header.headerEnd).toString("ascii"));
|
|
161
|
+
if (contentLength === null) {
|
|
162
|
+
writeErr("[mcp-transport] missing Content-Length header\n");
|
|
163
|
+
buffer = buffer.subarray(header.bodyStart);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const messageEnd = header.bodyStart + contentLength;
|
|
167
|
+
if (buffer.length < messageEnd) return;
|
|
168
|
+
framed = true;
|
|
169
|
+
const message = buffer.subarray(header.bodyStart, messageEnd).toString("utf8");
|
|
170
|
+
buffer = buffer.subarray(messageEnd);
|
|
171
|
+
onMessage(message);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const newline = buffer.indexOf(10);
|
|
175
|
+
if (newline === -1) return;
|
|
176
|
+
const line = buffer.subarray(0, newline).toString("utf8").replace(/\r$/, "");
|
|
177
|
+
buffer = buffer.subarray(newline + 1);
|
|
178
|
+
onMessage(line);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
push(chunk) {
|
|
183
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, "utf8");
|
|
184
|
+
buffer = Buffer.concat([buffer, bytes]);
|
|
185
|
+
processBuffer();
|
|
186
|
+
},
|
|
187
|
+
isFramed() {
|
|
188
|
+
return framed;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function createStdioTransport(handler) {
|
|
193
|
+
let parser = null;
|
|
194
|
+
let queue = Promise.resolve();
|
|
195
|
+
const writeResponse = (response) => {
|
|
196
|
+
const formatted = formatResponse(response, parser?.isFramed() ?? false);
|
|
197
|
+
if (typeof formatted === "string") {
|
|
198
|
+
process.stdout.write(formatted);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
for (const chunk of formatted) process.stdout.write(chunk);
|
|
202
|
+
};
|
|
203
|
+
const onData = (chunk) => parser?.push(chunk);
|
|
204
|
+
return {
|
|
205
|
+
start() {
|
|
206
|
+
parser = createMessageParser((message) => {
|
|
207
|
+
queue = queue.then(() => processLine(message, handler, writeResponse));
|
|
208
|
+
queue.catch((err) => {
|
|
209
|
+
process.stderr.write(`[mcp-transport] request processing failed: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
process.stdin.on("data", onData);
|
|
213
|
+
},
|
|
214
|
+
stop() {
|
|
215
|
+
process.stdin.off("data", onData);
|
|
216
|
+
parser = null;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/mcp/rest-proxy.ts
|
|
222
|
+
const DEFAULT_URL = "http://localhost:3111";
|
|
223
|
+
const DEFAULT_HEALTH_PROBE_TIMEOUT_MS = 2e3;
|
|
224
|
+
const CALL_TIMEOUT_MS = 15e3;
|
|
225
|
+
const LOCAL_MODE_TTL_MS = 3e4;
|
|
226
|
+
function probeTimeoutMs() {
|
|
227
|
+
const raw = process.env["AGENTMEMORY_PROBE_TIMEOUT_MS"];
|
|
228
|
+
if (!raw) return DEFAULT_HEALTH_PROBE_TIMEOUT_MS;
|
|
229
|
+
const n = Number(raw);
|
|
230
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n) : DEFAULT_HEALTH_PROBE_TIMEOUT_MS;
|
|
231
|
+
}
|
|
232
|
+
function forceProxy() {
|
|
233
|
+
const raw = process.env["AGENTMEMORY_FORCE_PROXY"];
|
|
234
|
+
return raw === "1" || raw === "true";
|
|
235
|
+
}
|
|
236
|
+
let cached = null;
|
|
237
|
+
let cachedAt = 0;
|
|
238
|
+
let probeInFlight = null;
|
|
239
|
+
function resolveEnvOrEmpty(name) {
|
|
240
|
+
const raw = process.env[name];
|
|
241
|
+
if (!raw) return "";
|
|
242
|
+
if (raw.startsWith("${") && raw.endsWith("}")) return "";
|
|
243
|
+
return raw;
|
|
244
|
+
}
|
|
245
|
+
function baseUrl() {
|
|
246
|
+
return (resolveEnvOrEmpty("AGENTMEMORY_URL") || DEFAULT_URL).replace(/\/+$/, "");
|
|
247
|
+
}
|
|
248
|
+
function authHeader() {
|
|
249
|
+
const secret = resolveEnvOrEmpty("AGENTMEMORY_SECRET");
|
|
250
|
+
return secret ? { authorization: `Bearer ${secret}` } : {};
|
|
251
|
+
}
|
|
252
|
+
const defaultLivezProbe = async (url, timeoutMs, headers) => {
|
|
253
|
+
const res = await fetch(`${url}/agentmemory/livez`, {
|
|
254
|
+
method: "GET",
|
|
255
|
+
headers,
|
|
256
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
257
|
+
});
|
|
258
|
+
return {
|
|
259
|
+
ok: res.ok,
|
|
260
|
+
status: res.status,
|
|
261
|
+
statusText: res.statusText
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
let livezProbe = defaultLivezProbe;
|
|
265
|
+
async function probe(url) {
|
|
266
|
+
const timeout = probeTimeoutMs();
|
|
267
|
+
try {
|
|
268
|
+
const res = await livezProbe(url, timeout, authHeader());
|
|
269
|
+
if (!res.ok) process.stderr.write(`[@agentmemory/mcp] livez probe ${url}/agentmemory/livez -> ${res.status ?? "?"} ${res.statusText ?? ""}; falling back to local InMemoryKV (set AGENTMEMORY_FORCE_PROXY=1 to skip the probe)\n`);
|
|
270
|
+
return res.ok;
|
|
271
|
+
} catch (err) {
|
|
272
|
+
process.stderr.write(`[@agentmemory/mcp] livez probe ${url}/agentmemory/livez failed in ${timeout}ms: ${err instanceof Error ? err.message : String(err)}; falling back to local InMemoryKV (set AGENTMEMORY_FORCE_PROXY=1 to skip the probe, or raise AGENTMEMORY_PROBE_TIMEOUT_MS)\n`);
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function invalidateHandle() {
|
|
277
|
+
cached = null;
|
|
278
|
+
cachedAt = 0;
|
|
279
|
+
}
|
|
280
|
+
async function resolveHandle() {
|
|
281
|
+
const now = Date.now();
|
|
282
|
+
if (cached) if (cached.mode === "local" && now - cachedAt >= LOCAL_MODE_TTL_MS) {
|
|
283
|
+
cached = null;
|
|
284
|
+
cachedAt = 0;
|
|
285
|
+
} else return cached;
|
|
286
|
+
if (probeInFlight) return probeInFlight;
|
|
287
|
+
const url = baseUrl();
|
|
288
|
+
const skipProbe = forceProxy();
|
|
289
|
+
probeInFlight = (async () => {
|
|
290
|
+
const up = skipProbe ? true : await probe(url);
|
|
291
|
+
if (skipProbe) process.stderr.write(`[@agentmemory/mcp] AGENTMEMORY_FORCE_PROXY set; skipping livez probe and trusting ${url}\n`);
|
|
292
|
+
if (up) {
|
|
293
|
+
const handle = {
|
|
294
|
+
mode: "proxy",
|
|
295
|
+
baseUrl: url,
|
|
296
|
+
call: async (path, init) => {
|
|
297
|
+
const res = await fetch(`${url}${path}`, {
|
|
298
|
+
...init,
|
|
299
|
+
headers: {
|
|
300
|
+
"content-type": "application/json",
|
|
301
|
+
...authHeader(),
|
|
302
|
+
...init?.headers
|
|
303
|
+
},
|
|
304
|
+
signal: AbortSignal.timeout(CALL_TIMEOUT_MS)
|
|
305
|
+
});
|
|
306
|
+
if (!res.ok) throw new Error(`${init?.method || "GET"} ${path} -> ${res.status} ${res.statusText}`);
|
|
307
|
+
const text = await res.text();
|
|
308
|
+
return text ? JSON.parse(text) : null;
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
cached = handle;
|
|
312
|
+
cachedAt = Date.now();
|
|
313
|
+
return handle;
|
|
314
|
+
}
|
|
315
|
+
const local = { mode: "local" };
|
|
316
|
+
cached = local;
|
|
317
|
+
cachedAt = Date.now();
|
|
318
|
+
return local;
|
|
319
|
+
})();
|
|
320
|
+
try {
|
|
321
|
+
return await probeInFlight;
|
|
322
|
+
} finally {
|
|
323
|
+
probeInFlight = null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
//#endregion
|
|
327
|
+
//#region src/mcp/standalone.ts
|
|
328
|
+
const IMPLEMENTED_TOOLS = new Set([
|
|
329
|
+
"memory_save",
|
|
330
|
+
"memory_update",
|
|
331
|
+
"memory_recall",
|
|
332
|
+
"memory_smart_search",
|
|
333
|
+
"memory_sessions",
|
|
334
|
+
"memory_export",
|
|
335
|
+
"memory_audit",
|
|
336
|
+
"memory_governance_delete"
|
|
337
|
+
]);
|
|
338
|
+
const SERVER_INFO = {
|
|
339
|
+
name: "agentmemory",
|
|
340
|
+
version: VERSION,
|
|
341
|
+
protocolVersion: "2024-11-05"
|
|
342
|
+
};
|
|
343
|
+
const kv = new InMemoryKV(getStandalonePersistPath());
|
|
344
|
+
let modeAnnounced = false;
|
|
345
|
+
function displayAgentmemoryUrl() {
|
|
346
|
+
const raw = process.env["AGENTMEMORY_URL"];
|
|
347
|
+
if (!raw || raw.startsWith("${") && raw.endsWith("}")) return "http://localhost:3111";
|
|
348
|
+
return raw;
|
|
349
|
+
}
|
|
350
|
+
function announceMode(handle) {
|
|
351
|
+
if (modeAnnounced) return;
|
|
352
|
+
modeAnnounced = true;
|
|
353
|
+
if (handle.mode === "proxy") process.stderr.write(`[@agentmemory/mcp] proxying to agentmemory server at ${handle.baseUrl}\n`);
|
|
354
|
+
else {
|
|
355
|
+
const fullToolCount = getAllTools().length;
|
|
356
|
+
process.stderr.write(`[@agentmemory/mcp] no server reachable at ${displayAgentmemoryUrl()}; running reduced LOCAL FALLBACK with ${IMPLEMENTED_TOOLS.size} of ${fullToolCount} tools. Start 'npx @agentmemory/agentmemory' (and point AGENTMEMORY_URL at it) to unlock all ${fullToolCount} tools.\n`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function normalizeList(value) {
|
|
360
|
+
if (!value) return [];
|
|
361
|
+
if (Array.isArray(value)) return value.map((v) => typeof v === "string" ? v.trim() : "").filter((v) => v.length > 0);
|
|
362
|
+
if (typeof value === "string") return value.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
363
|
+
return [];
|
|
364
|
+
}
|
|
365
|
+
const DEFAULT_LIMIT = 10;
|
|
366
|
+
const MAX_LIMIT = 100;
|
|
367
|
+
function parseLimit(raw, fallback = DEFAULT_LIMIT) {
|
|
368
|
+
if (typeof raw !== "number" && typeof raw !== "string") return fallback;
|
|
369
|
+
const n = Number(raw);
|
|
370
|
+
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
371
|
+
return Math.min(Math.floor(n), MAX_LIMIT);
|
|
372
|
+
}
|
|
373
|
+
function textResponse(payload, pretty = false) {
|
|
374
|
+
return { content: [{
|
|
375
|
+
type: "text",
|
|
376
|
+
text: JSON.stringify(payload, null, pretty ? 2 : 0)
|
|
377
|
+
}] };
|
|
378
|
+
}
|
|
379
|
+
function validate(toolName, args) {
|
|
380
|
+
if (!IMPLEMENTED_TOOLS.has(toolName)) throw new Error(`Unknown tool: ${toolName}`);
|
|
381
|
+
const v = { tool: toolName };
|
|
382
|
+
switch (toolName) {
|
|
383
|
+
case "memory_save": {
|
|
384
|
+
const content = args["content"];
|
|
385
|
+
if (typeof content !== "string" || !content.trim()) throw new Error("content is required");
|
|
386
|
+
v.content = content;
|
|
387
|
+
v.type = args["type"] || "fact";
|
|
388
|
+
v.concepts = normalizeList(args["concepts"]);
|
|
389
|
+
v.files = normalizeList(args["files"]);
|
|
390
|
+
return v;
|
|
391
|
+
}
|
|
392
|
+
case "memory_update": {
|
|
393
|
+
const memoryId = args["memoryId"];
|
|
394
|
+
if (typeof memoryId !== "string" || !memoryId.trim()) throw new Error("memoryId is required");
|
|
395
|
+
const content = args["content"];
|
|
396
|
+
if (typeof content !== "string" || !content.trim()) throw new Error("content is required");
|
|
397
|
+
v.memoryId = memoryId;
|
|
398
|
+
v.content = content;
|
|
399
|
+
if (typeof args["type"] === "string" && args["type"].trim()) v.type = args["type"];
|
|
400
|
+
v.concepts = normalizeList(args["concepts"]);
|
|
401
|
+
v.files = normalizeList(args["files"]);
|
|
402
|
+
return v;
|
|
403
|
+
}
|
|
404
|
+
case "memory_recall":
|
|
405
|
+
case "memory_smart_search": {
|
|
406
|
+
const query = args["query"];
|
|
407
|
+
if (typeof query !== "string" || !query.trim()) throw new Error("query is required");
|
|
408
|
+
v.query = query.trim();
|
|
409
|
+
v.limit = parseLimit(args["limit"]);
|
|
410
|
+
const fmt = args["format"];
|
|
411
|
+
if (typeof fmt === "string" && fmt.trim()) v.format = fmt.trim().toLowerCase();
|
|
412
|
+
const budget = args["token_budget"];
|
|
413
|
+
if (typeof budget === "number" && Number.isFinite(budget) && budget > 0) v.tokenBudget = Math.floor(budget);
|
|
414
|
+
else if (typeof budget === "string" && budget.trim()) {
|
|
415
|
+
const n = Number(budget);
|
|
416
|
+
if (Number.isFinite(n) && n > 0) v.tokenBudget = Math.floor(n);
|
|
417
|
+
}
|
|
418
|
+
return v;
|
|
419
|
+
}
|
|
420
|
+
case "memory_sessions":
|
|
421
|
+
v.limit = parseLimit(args["limit"], 20);
|
|
422
|
+
return v;
|
|
423
|
+
case "memory_governance_delete": {
|
|
424
|
+
const ids = normalizeList(args["memoryIds"]);
|
|
425
|
+
if (ids.length === 0) throw new Error("memoryIds is required");
|
|
426
|
+
v.memoryIds = ids;
|
|
427
|
+
v.reason = args["reason"] || "plugin skill request";
|
|
428
|
+
return v;
|
|
429
|
+
}
|
|
430
|
+
case "memory_export": return v;
|
|
431
|
+
case "memory_audit":
|
|
432
|
+
v.limit = parseLimit(args["limit"], 50);
|
|
433
|
+
return v;
|
|
434
|
+
default: throw new Error(`Unknown tool: ${toolName}`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
async function handleProxy(v, handle) {
|
|
438
|
+
switch (v.tool) {
|
|
439
|
+
case "memory_save": return textResponse(await handle.call("/agentmemory/remember", {
|
|
440
|
+
method: "POST",
|
|
441
|
+
body: JSON.stringify({
|
|
442
|
+
content: v.content,
|
|
443
|
+
type: v.type,
|
|
444
|
+
concepts: v.concepts,
|
|
445
|
+
files: v.files
|
|
446
|
+
})
|
|
447
|
+
}), true);
|
|
448
|
+
case "memory_update": {
|
|
449
|
+
const body = {
|
|
450
|
+
memoryId: v.memoryId,
|
|
451
|
+
content: v.content
|
|
452
|
+
};
|
|
453
|
+
if (v.type) body["type"] = v.type;
|
|
454
|
+
if (v.concepts) body["concepts"] = v.concepts;
|
|
455
|
+
if (v.files) body["files"] = v.files;
|
|
456
|
+
return textResponse(await handle.call("/agentmemory/memories/update", {
|
|
457
|
+
method: "PUT",
|
|
458
|
+
body: JSON.stringify(body)
|
|
459
|
+
}), true);
|
|
460
|
+
}
|
|
461
|
+
case "memory_recall": {
|
|
462
|
+
const body = {
|
|
463
|
+
query: v.query,
|
|
464
|
+
limit: v.limit,
|
|
465
|
+
format: v.format ?? "full"
|
|
466
|
+
};
|
|
467
|
+
if (v.tokenBudget != null) body["token_budget"] = v.tokenBudget;
|
|
468
|
+
return textResponse(await handle.call("/agentmemory/search", {
|
|
469
|
+
method: "POST",
|
|
470
|
+
body: JSON.stringify(body)
|
|
471
|
+
}), true);
|
|
472
|
+
}
|
|
473
|
+
case "memory_smart_search": {
|
|
474
|
+
const body = {
|
|
475
|
+
query: v.query,
|
|
476
|
+
limit: v.limit
|
|
477
|
+
};
|
|
478
|
+
if (v.format != null) body["format"] = v.format;
|
|
479
|
+
if (v.tokenBudget != null) body["token_budget"] = v.tokenBudget;
|
|
480
|
+
return textResponse(await handle.call("/agentmemory/smart-search", {
|
|
481
|
+
method: "POST",
|
|
482
|
+
body: JSON.stringify(body)
|
|
483
|
+
}), true);
|
|
484
|
+
}
|
|
485
|
+
case "memory_sessions": return textResponse(await handle.call(`/agentmemory/sessions?limit=${v.limit}`, { method: "GET" }), true);
|
|
486
|
+
case "memory_governance_delete": return textResponse(await handle.call("/agentmemory/governance/memories", {
|
|
487
|
+
method: "DELETE",
|
|
488
|
+
body: JSON.stringify({
|
|
489
|
+
memoryIds: v.memoryIds,
|
|
490
|
+
reason: v.reason
|
|
491
|
+
})
|
|
492
|
+
}));
|
|
493
|
+
case "memory_export": return textResponse(await handle.call("/agentmemory/export", { method: "GET" }), true);
|
|
494
|
+
case "memory_audit": return textResponse(await handle.call(`/agentmemory/audit?limit=${v.limit}`, { method: "GET" }), true);
|
|
495
|
+
default: throw new Error(`Unknown tool: ${v.tool}`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
async function handleLocal(v, kvInstance) {
|
|
499
|
+
switch (v.tool) {
|
|
500
|
+
case "memory_save": {
|
|
501
|
+
const id = generateId("mem");
|
|
502
|
+
const isoNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
503
|
+
await kvInstance.set("mem:memories", id, {
|
|
504
|
+
id,
|
|
505
|
+
type: v.type,
|
|
506
|
+
title: (v.content || "").slice(0, 80),
|
|
507
|
+
content: v.content,
|
|
508
|
+
concepts: v.concepts,
|
|
509
|
+
files: v.files,
|
|
510
|
+
createdAt: isoNow,
|
|
511
|
+
updatedAt: isoNow,
|
|
512
|
+
strength: 7,
|
|
513
|
+
version: 1,
|
|
514
|
+
isLatest: true,
|
|
515
|
+
sessionIds: []
|
|
516
|
+
});
|
|
517
|
+
kvInstance.persist();
|
|
518
|
+
return textResponse({ saved: id });
|
|
519
|
+
}
|
|
520
|
+
case "memory_update": {
|
|
521
|
+
const existing = await kvInstance.get("mem:memories", v.memoryId);
|
|
522
|
+
if (!existing) return textResponse({
|
|
523
|
+
success: false,
|
|
524
|
+
error: "memory not found"
|
|
525
|
+
});
|
|
526
|
+
const oldVersion = typeof existing["version"] === "number" ? existing["version"] : 1;
|
|
527
|
+
const newVersion = oldVersion + 1;
|
|
528
|
+
const isoNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
529
|
+
const updated = {
|
|
530
|
+
...existing,
|
|
531
|
+
type: v.type ?? existing["type"],
|
|
532
|
+
title: (v.content || "").slice(0, 80),
|
|
533
|
+
content: v.content,
|
|
534
|
+
concepts: v.concepts ?? existing["concepts"],
|
|
535
|
+
files: v.files ?? existing["files"],
|
|
536
|
+
updatedAt: isoNow,
|
|
537
|
+
version: newVersion,
|
|
538
|
+
isLatest: true,
|
|
539
|
+
supersedes: [...Array.isArray(existing["supersedes"]) ? existing["supersedes"] : [], v.memoryId]
|
|
540
|
+
};
|
|
541
|
+
await kvInstance.set("mem:memories", v.memoryId, updated);
|
|
542
|
+
kvInstance.persist();
|
|
543
|
+
return textResponse({
|
|
544
|
+
success: true,
|
|
545
|
+
memory: updated,
|
|
546
|
+
oldVersion,
|
|
547
|
+
newVersion
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
case "memory_recall":
|
|
551
|
+
case "memory_smart_search": {
|
|
552
|
+
const query = (v.query || "").toLowerCase();
|
|
553
|
+
const limit = v.limit ?? DEFAULT_LIMIT;
|
|
554
|
+
return textResponse({
|
|
555
|
+
mode: "compact",
|
|
556
|
+
results: (await kvInstance.list("mem:memories")).filter((m) => {
|
|
557
|
+
const text = [
|
|
558
|
+
typeof m["title"] === "string" ? m["title"] : "",
|
|
559
|
+
typeof m["content"] === "string" ? m["content"] : "",
|
|
560
|
+
Array.isArray(m["files"]) ? m["files"].join(" ") : "",
|
|
561
|
+
Array.isArray(m["concepts"]) ? m["concepts"].join(" ") : "",
|
|
562
|
+
Array.isArray(m["sessionIds"]) ? m["sessionIds"].join(" ") : "",
|
|
563
|
+
typeof m["id"] === "string" ? m["id"] : ""
|
|
564
|
+
].join(" ").toLowerCase();
|
|
565
|
+
return query.split(/\s+/).every((word) => text.includes(word));
|
|
566
|
+
}).slice(0, limit)
|
|
567
|
+
}, true);
|
|
568
|
+
}
|
|
569
|
+
case "memory_sessions": {
|
|
570
|
+
const sessions = await kvInstance.list("mem:sessions");
|
|
571
|
+
const limit = v.limit ?? 20;
|
|
572
|
+
return textResponse({ sessions: sessions.slice(0, limit) }, true);
|
|
573
|
+
}
|
|
574
|
+
case "memory_governance_delete": {
|
|
575
|
+
let deleted = 0;
|
|
576
|
+
for (const id of v.memoryIds || []) if (await kvInstance.get("mem:memories", id)) {
|
|
577
|
+
await kvInstance.delete("mem:memories", id);
|
|
578
|
+
deleted++;
|
|
579
|
+
}
|
|
580
|
+
kvInstance.persist();
|
|
581
|
+
return textResponse({
|
|
582
|
+
deleted,
|
|
583
|
+
requested: (v.memoryIds || []).length,
|
|
584
|
+
reason: v.reason
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
case "memory_export": return textResponse({
|
|
588
|
+
version: VERSION,
|
|
589
|
+
memories: await kvInstance.list("mem:memories"),
|
|
590
|
+
sessions: await kvInstance.list("mem:sessions")
|
|
591
|
+
}, true);
|
|
592
|
+
case "memory_audit": {
|
|
593
|
+
const entries = await kvInstance.list("mem:audit");
|
|
594
|
+
const limit = v.limit ?? 50;
|
|
595
|
+
return textResponse({ entries: entries.slice(0, limit) }, true);
|
|
596
|
+
}
|
|
597
|
+
default: throw new Error(`Unknown tool: ${v.tool}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
async function handleProxyGeneric(toolName, args, handle) {
|
|
601
|
+
const result = await handle.call("/agentmemory/mcp/call", {
|
|
602
|
+
method: "POST",
|
|
603
|
+
body: JSON.stringify({
|
|
604
|
+
name: toolName,
|
|
605
|
+
arguments: args
|
|
606
|
+
})
|
|
607
|
+
});
|
|
608
|
+
if (result && Array.isArray(result.content)) return { content: result.content };
|
|
609
|
+
return textResponse(result, true);
|
|
610
|
+
}
|
|
611
|
+
async function handleToolCall(toolName, args, kvInstance = kv) {
|
|
612
|
+
const handle = await resolveHandle();
|
|
613
|
+
announceMode(handle);
|
|
614
|
+
if (!IMPLEMENTED_TOOLS.has(toolName)) {
|
|
615
|
+
if (handle.mode === "proxy") try {
|
|
616
|
+
return await handleProxyGeneric(toolName, args, handle);
|
|
617
|
+
} catch (err) {
|
|
618
|
+
process.stderr.write(`[@agentmemory/mcp] proxy call failed for ${toolName}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
619
|
+
invalidateHandle();
|
|
620
|
+
throw err;
|
|
621
|
+
}
|
|
622
|
+
throw new Error(`Unknown tool: ${toolName} (local fallback supports only ${[...IMPLEMENTED_TOOLS].join(", ")}; start an agentmemory server and set AGENTMEMORY_URL to use the full tool set)`);
|
|
623
|
+
}
|
|
624
|
+
const validated = validate(toolName, args);
|
|
625
|
+
if (handle.mode === "proxy") try {
|
|
626
|
+
return await handleProxy(validated, handle);
|
|
627
|
+
} catch (err) {
|
|
628
|
+
process.stderr.write(`[@agentmemory/mcp] proxy call failed for ${toolName}: ${err instanceof Error ? err.message : String(err)}; invalidating handle and falling back to local KV\n`);
|
|
629
|
+
invalidateHandle();
|
|
630
|
+
}
|
|
631
|
+
return handleLocal(validated, kvInstance);
|
|
632
|
+
}
|
|
633
|
+
async function handleToolsList() {
|
|
634
|
+
const debug = process.env["AGENTMEMORY_DEBUG"] === "1" || process.env["AGENTMEMORY_DEBUG"] === "true";
|
|
635
|
+
const handle = await resolveHandle();
|
|
636
|
+
announceMode(handle);
|
|
637
|
+
if (debug) process.stderr.write(`[@agentmemory/mcp] tools/list: handle.mode=${handle.mode}${handle.mode === "proxy" ? ` baseUrl=${handle.baseUrl}` : ""}\n`);
|
|
638
|
+
if (handle.mode === "proxy") try {
|
|
639
|
+
const remote = await handle.call("/agentmemory/mcp/tools", { method: "GET" });
|
|
640
|
+
if (debug) {
|
|
641
|
+
const shape = remote === null ? "null" : typeof remote !== "object" ? typeof remote : `keys=${Object.keys(remote).join(",")} toolsType=${Array.isArray(remote.tools) ? `array(len=${remote.tools.length})` : typeof remote.tools}`;
|
|
642
|
+
process.stderr.write(`[@agentmemory/mcp] tools/list: remote response shape: ${shape}\n`);
|
|
643
|
+
}
|
|
644
|
+
if (remote && Array.isArray(remote.tools)) {
|
|
645
|
+
if (debug) process.stderr.write(`[@agentmemory/mcp] tools/list: returning ${remote.tools.length} tools from server\n`);
|
|
646
|
+
return { tools: remote.tools };
|
|
647
|
+
}
|
|
648
|
+
process.stderr.write(`[@agentmemory/mcp] tools/list: server returned unexpected shape (no .tools array); falling back to local IMPLEMENTED_TOOLS list. Set AGENTMEMORY_DEBUG=1 to inspect response.\n`);
|
|
649
|
+
} catch (err) {
|
|
650
|
+
process.stderr.write(`[@agentmemory/mcp] tools/list proxy failed: ${err instanceof Error ? err.message : String(err)}; falling back to local list\n`);
|
|
651
|
+
invalidateHandle();
|
|
652
|
+
}
|
|
653
|
+
const fallback = getAllTools().filter((t) => IMPLEMENTED_TOOLS.has(t.name));
|
|
654
|
+
if (debug) process.stderr.write(`[@agentmemory/mcp] tools/list: returning ${fallback.length} local fallback tools (${fallback.map((t) => t.name).join(",")})\n`);
|
|
655
|
+
return { tools: fallback };
|
|
656
|
+
}
|
|
657
|
+
const transport = createStdioTransport(async (method, params) => {
|
|
658
|
+
switch (method) {
|
|
659
|
+
case "initialize": return {
|
|
660
|
+
protocolVersion: SERVER_INFO.protocolVersion,
|
|
661
|
+
capabilities: { tools: { listChanged: false } },
|
|
662
|
+
serverInfo: {
|
|
663
|
+
name: SERVER_INFO.name,
|
|
664
|
+
version: SERVER_INFO.version
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
case "notifications/initialized": return {};
|
|
668
|
+
case "tools/list": return handleToolsList();
|
|
669
|
+
case "tools/call": {
|
|
670
|
+
const toolName = params.name;
|
|
671
|
+
const toolArgs = params.arguments || {};
|
|
672
|
+
try {
|
|
673
|
+
return await handleToolCall(toolName, toolArgs);
|
|
674
|
+
} catch (err) {
|
|
675
|
+
return {
|
|
676
|
+
content: [{
|
|
677
|
+
type: "text",
|
|
678
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`
|
|
679
|
+
}],
|
|
680
|
+
isError: true
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
default: throw new Error(`Unknown method: ${method}`);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
process.stderr.write(`[@agentmemory/mcp] Standalone MCP server v${SERVER_INFO.version} starting...\n`);
|
|
688
|
+
transport.start();
|
|
689
|
+
process.on("SIGINT", () => {
|
|
690
|
+
kv.persist();
|
|
691
|
+
process.exit(0);
|
|
692
|
+
});
|
|
693
|
+
process.on("SIGTERM", () => {
|
|
694
|
+
kv.persist();
|
|
695
|
+
process.exit(0);
|
|
696
|
+
});
|
|
697
|
+
//#endregion
|
|
698
|
+
export {};
|
|
699
|
+
|
|
700
|
+
//# sourceMappingURL=standalone-C6KzNkt5.mjs.map
|