@agentmemory/agentmemory 0.8.0 → 0.8.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/README.md +573 -702
- package/dist/cli.mjs +419 -95
- package/dist/cli.mjs.map +1 -1
- package/dist/docker-compose.yml +5 -5
- package/dist/iii-config.docker.yaml +51 -0
- package/dist/iii-config.yaml +2 -2
- package/dist/index.mjs +408 -184
- package/dist/index.mjs.map +1 -1
- package/dist/{src-qOdKVNQz.mjs → src-BuDB8dPq.mjs} +410 -1328
- package/dist/src-BuDB8dPq.mjs.map +1 -0
- package/dist/standalone-CxAvUMQk.mjs +267 -0
- package/dist/standalone-CxAvUMQk.mjs.map +1 -0
- package/dist/standalone.d.mts +22 -1
- package/dist/standalone.d.mts.map +1 -0
- package/dist/standalone.mjs +94 -61
- package/dist/standalone.mjs.map +1 -1
- package/dist/tools-registry-B9EXJvIf.mjs +1089 -0
- package/dist/tools-registry-B9EXJvIf.mjs.map +1 -0
- package/dist/viewer/index.html +2970 -0
- package/docker-compose.yml +5 -5
- package/iii-config.yaml +2 -2
- package/package.json +11 -4
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/src-qOdKVNQz.mjs.map +0 -1
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { i as generateId } from "./cli.mjs";
|
|
2
|
+
import { n as VERSION, o as getStandalonePersistPath, t as getVisibleTools } from "./tools-registry-B9EXJvIf.mjs";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
6
|
+
|
|
7
|
+
//#region src/mcp/in-memory-kv.ts
|
|
8
|
+
var InMemoryKV = class {
|
|
9
|
+
store = /* @__PURE__ */ new Map();
|
|
10
|
+
constructor(persistPath) {
|
|
11
|
+
this.persistPath = persistPath;
|
|
12
|
+
if (persistPath && existsSync(persistPath)) try {
|
|
13
|
+
const data = JSON.parse(readFileSync(persistPath, "utf-8"));
|
|
14
|
+
for (const [scope, entries] of Object.entries(data)) {
|
|
15
|
+
const map = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const [key, value] of Object.entries(entries)) map.set(key, value);
|
|
17
|
+
this.store.set(scope, map);
|
|
18
|
+
}
|
|
19
|
+
} catch {}
|
|
20
|
+
}
|
|
21
|
+
async get(scope, key) {
|
|
22
|
+
return this.store.get(scope)?.get(key) ?? null;
|
|
23
|
+
}
|
|
24
|
+
async set(scope, key, data) {
|
|
25
|
+
if (!this.store.has(scope)) this.store.set(scope, /* @__PURE__ */ new Map());
|
|
26
|
+
this.store.get(scope).set(key, data);
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
async delete(scope, key) {
|
|
30
|
+
this.store.get(scope)?.delete(key);
|
|
31
|
+
}
|
|
32
|
+
async list(scope) {
|
|
33
|
+
const entries = this.store.get(scope);
|
|
34
|
+
return entries ? Array.from(entries.values()) : [];
|
|
35
|
+
}
|
|
36
|
+
persist() {
|
|
37
|
+
if (!this.persistPath) return;
|
|
38
|
+
try {
|
|
39
|
+
const dir = dirname(this.persistPath);
|
|
40
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
41
|
+
const data = {};
|
|
42
|
+
for (const [scope, entries] of this.store) data[scope] = Object.fromEntries(entries);
|
|
43
|
+
writeFileSync(this.persistPath, JSON.stringify(data), "utf-8");
|
|
44
|
+
} catch (err) {
|
|
45
|
+
process.stderr.write(`[agentmemory-mcp] Persist failed: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/mcp/transport.ts
|
|
52
|
+
function isNotification(req) {
|
|
53
|
+
return req.id === void 0 || req.id === null;
|
|
54
|
+
}
|
|
55
|
+
function isValidId(id) {
|
|
56
|
+
return id === void 0 || id === null || typeof id === "string" || typeof id === "number";
|
|
57
|
+
}
|
|
58
|
+
async function processLine(line, handler, writeOut, writeErr = (msg) => process.stderr.write(msg)) {
|
|
59
|
+
const trimmed = line.trim();
|
|
60
|
+
if (!trimmed) return;
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(trimmed);
|
|
64
|
+
} catch {
|
|
65
|
+
writeOut({
|
|
66
|
+
jsonrpc: "2.0",
|
|
67
|
+
id: null,
|
|
68
|
+
error: {
|
|
69
|
+
code: -32700,
|
|
70
|
+
message: "Parse error"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const request = parsed;
|
|
76
|
+
const rawId = request?.id;
|
|
77
|
+
if (!request || typeof request !== "object" || request.jsonrpc !== "2.0" || typeof request.method !== "string") {
|
|
78
|
+
if (typeof rawId === "string" || typeof rawId === "number") writeOut({
|
|
79
|
+
jsonrpc: "2.0",
|
|
80
|
+
id: rawId,
|
|
81
|
+
error: {
|
|
82
|
+
code: -32600,
|
|
83
|
+
message: "Invalid Request"
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (!isValidId(rawId)) {
|
|
89
|
+
writeOut({
|
|
90
|
+
jsonrpc: "2.0",
|
|
91
|
+
id: null,
|
|
92
|
+
error: {
|
|
93
|
+
code: -32600,
|
|
94
|
+
message: "Invalid Request: id must be string, number, or null"
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const notification = isNotification(request);
|
|
100
|
+
try {
|
|
101
|
+
const result = await handler(request.method, request.params || {});
|
|
102
|
+
if (notification) return;
|
|
103
|
+
writeOut({
|
|
104
|
+
jsonrpc: "2.0",
|
|
105
|
+
id: request.id,
|
|
106
|
+
result
|
|
107
|
+
});
|
|
108
|
+
} catch (err) {
|
|
109
|
+
if (notification) {
|
|
110
|
+
writeErr(`[mcp-transport] notification handler error for ${request.method}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
writeOut({
|
|
114
|
+
jsonrpc: "2.0",
|
|
115
|
+
id: request.id,
|
|
116
|
+
error: {
|
|
117
|
+
code: -32603,
|
|
118
|
+
message: err instanceof Error ? err.message : String(err)
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function createStdioTransport(handler) {
|
|
124
|
+
let rl = null;
|
|
125
|
+
const writeResponse = (response) => {
|
|
126
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
127
|
+
};
|
|
128
|
+
const onLine = (line) => processLine(line, handler, writeResponse);
|
|
129
|
+
return {
|
|
130
|
+
start() {
|
|
131
|
+
rl = createInterface({ input: process.stdin });
|
|
132
|
+
rl.on("line", onLine);
|
|
133
|
+
},
|
|
134
|
+
stop() {
|
|
135
|
+
rl?.close();
|
|
136
|
+
rl = null;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/mcp/standalone.ts
|
|
143
|
+
const IMPLEMENTED_TOOLS = new Set([
|
|
144
|
+
"memory_save",
|
|
145
|
+
"memory_recall",
|
|
146
|
+
"memory_sessions",
|
|
147
|
+
"memory_export",
|
|
148
|
+
"memory_audit"
|
|
149
|
+
]);
|
|
150
|
+
const SERVER_INFO = {
|
|
151
|
+
name: "agentmemory",
|
|
152
|
+
version: VERSION,
|
|
153
|
+
protocolVersion: "2024-11-05"
|
|
154
|
+
};
|
|
155
|
+
const kv = new InMemoryKV(getStandalonePersistPath());
|
|
156
|
+
async function handleToolCall(toolName, args, kvInstance = kv) {
|
|
157
|
+
switch (toolName) {
|
|
158
|
+
case "memory_save": {
|
|
159
|
+
const content = args.content;
|
|
160
|
+
if (!content?.trim()) throw new Error("content is required");
|
|
161
|
+
const id = generateId("mem");
|
|
162
|
+
const isoNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
163
|
+
await kvInstance.set("mem:memories", id, {
|
|
164
|
+
id,
|
|
165
|
+
type: args.type || "fact",
|
|
166
|
+
title: content.slice(0, 80),
|
|
167
|
+
content,
|
|
168
|
+
concepts: args.concepts ? args.concepts.split(",").map((c) => c.trim()) : [],
|
|
169
|
+
files: args.files ? args.files.split(",").map((f) => f.trim()) : [],
|
|
170
|
+
createdAt: isoNow,
|
|
171
|
+
updatedAt: isoNow,
|
|
172
|
+
strength: 7,
|
|
173
|
+
version: 1,
|
|
174
|
+
isLatest: true,
|
|
175
|
+
sessionIds: []
|
|
176
|
+
});
|
|
177
|
+
kvInstance.persist();
|
|
178
|
+
return { content: [{
|
|
179
|
+
type: "text",
|
|
180
|
+
text: JSON.stringify({ saved: id })
|
|
181
|
+
}] };
|
|
182
|
+
}
|
|
183
|
+
case "memory_recall": {
|
|
184
|
+
const query = args.query?.toLowerCase() || "";
|
|
185
|
+
const limit = args.limit || 10;
|
|
186
|
+
const results = (await kvInstance.list("mem:memories")).filter((m) => {
|
|
187
|
+
return `${m.title} ${m.content}`.toLowerCase().includes(query);
|
|
188
|
+
}).slice(0, limit);
|
|
189
|
+
return { content: [{
|
|
190
|
+
type: "text",
|
|
191
|
+
text: JSON.stringify(results, null, 2)
|
|
192
|
+
}] };
|
|
193
|
+
}
|
|
194
|
+
case "memory_sessions": {
|
|
195
|
+
const sessions = await kvInstance.list("mem:sessions");
|
|
196
|
+
return { content: [{
|
|
197
|
+
type: "text",
|
|
198
|
+
text: JSON.stringify({ sessions }, null, 2)
|
|
199
|
+
}] };
|
|
200
|
+
}
|
|
201
|
+
case "memory_export": {
|
|
202
|
+
const memories = await kvInstance.list("mem:memories");
|
|
203
|
+
const sessions = await kvInstance.list("mem:sessions");
|
|
204
|
+
return { content: [{
|
|
205
|
+
type: "text",
|
|
206
|
+
text: JSON.stringify({
|
|
207
|
+
version: VERSION,
|
|
208
|
+
memories,
|
|
209
|
+
sessions
|
|
210
|
+
}, null, 2)
|
|
211
|
+
}] };
|
|
212
|
+
}
|
|
213
|
+
case "memory_audit": {
|
|
214
|
+
const entries = await kvInstance.list("mem:audit");
|
|
215
|
+
const limit = args.limit || 50;
|
|
216
|
+
return { content: [{
|
|
217
|
+
type: "text",
|
|
218
|
+
text: JSON.stringify(entries.slice(0, limit), null, 2)
|
|
219
|
+
}] };
|
|
220
|
+
}
|
|
221
|
+
default: throw new Error(`Unknown tool: ${toolName}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const transport = createStdioTransport(async (method, params) => {
|
|
225
|
+
switch (method) {
|
|
226
|
+
case "initialize": return {
|
|
227
|
+
protocolVersion: SERVER_INFO.protocolVersion,
|
|
228
|
+
capabilities: { tools: { listChanged: false } },
|
|
229
|
+
serverInfo: {
|
|
230
|
+
name: SERVER_INFO.name,
|
|
231
|
+
version: SERVER_INFO.version
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
case "notifications/initialized": return {};
|
|
235
|
+
case "tools/list": return { tools: getVisibleTools().filter((t) => IMPLEMENTED_TOOLS.has(t.name)) };
|
|
236
|
+
case "tools/call": {
|
|
237
|
+
const toolName = params.name;
|
|
238
|
+
const toolArgs = params.arguments || {};
|
|
239
|
+
try {
|
|
240
|
+
return await handleToolCall(toolName, toolArgs);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
return {
|
|
243
|
+
content: [{
|
|
244
|
+
type: "text",
|
|
245
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`
|
|
246
|
+
}],
|
|
247
|
+
isError: true
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
default: throw new Error(`Unknown method: ${method}`);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
process.stderr.write(`[agentmemory-mcp] Standalone MCP server v${SERVER_INFO.version} starting...\n`);
|
|
255
|
+
transport.start();
|
|
256
|
+
process.on("SIGINT", () => {
|
|
257
|
+
kv.persist();
|
|
258
|
+
process.exit(0);
|
|
259
|
+
});
|
|
260
|
+
process.on("SIGTERM", () => {
|
|
261
|
+
kv.persist();
|
|
262
|
+
process.exit(0);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
//#endregion
|
|
266
|
+
export { };
|
|
267
|
+
//# sourceMappingURL=standalone-CxAvUMQk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone-CxAvUMQk.mjs","names":[],"sources":["../src/mcp/in-memory-kv.ts","../src/mcp/transport.ts","../src/mcp/standalone.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nexport class InMemoryKV {\n private store = new Map<string, Map<string, unknown>>();\n\n constructor(private persistPath?: string) {\n if (persistPath && existsSync(persistPath)) {\n try {\n const data = JSON.parse(readFileSync(persistPath, \"utf-8\"));\n for (const [scope, entries] of Object.entries(data)) {\n const map = new Map<string, unknown>();\n for (const [key, value] of Object.entries(\n entries as Record<string, unknown>,\n )) {\n map.set(key, value);\n }\n this.store.set(scope, map);\n }\n } catch {\n // start fresh\n }\n }\n }\n\n async get<T = unknown>(scope: string, key: string): Promise<T | null> {\n return (this.store.get(scope)?.get(key) as T) ?? null;\n }\n\n async set<T = unknown>(scope: string, key: string, data: T): Promise<T> {\n if (!this.store.has(scope)) this.store.set(scope, new Map());\n this.store.get(scope)!.set(key, data);\n return data;\n }\n\n async delete(scope: string, key: string): Promise<void> {\n this.store.get(scope)?.delete(key);\n }\n\n async list<T = unknown>(scope: string): Promise<T[]> {\n const entries = this.store.get(scope);\n return entries ? (Array.from(entries.values()) as T[]) : [];\n }\n\n persist(): void {\n if (!this.persistPath) return;\n try {\n const dir = dirname(this.persistPath);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n const data: Record<string, Record<string, unknown>> = {};\n for (const [scope, entries] of this.store) {\n data[scope] = Object.fromEntries(entries);\n }\n writeFileSync(this.persistPath, JSON.stringify(data), \"utf-8\");\n } catch (err) {\n process.stderr.write(\n `[agentmemory-mcp] Persist failed: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n }\n }\n}\n","import { createInterface } from \"node:readline\";\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id?: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\";\n id: string | number | null;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\nexport type RequestHandler = (\n method: string,\n params: Record<string, unknown>,\n) => Promise<unknown>;\n\n// JSON-RPC 2.0 notifications are messages without an `id` field. The spec\n// (and the MCP transport contract) requires the server to NOT send a\n// response for notifications. Some clients tolerate spurious responses;\n// stricter clients (e.g. Codex CLI) treat them as protocol violations and\n// close the transport. See agentmemory#129.\nfunction isNotification(req: JsonRpcRequest): boolean {\n return req.id === undefined || req.id === null;\n}\n\n// Per JSON-RPC 2.0 §4, a valid request id must be a String, Number, or Null\n// (Null is technically only allowed in responses; in requests, omitting id\n// is the convention for notifications, which we treat the same as null).\n// Any other runtime type (object, array, boolean) is an Invalid Request.\nfunction isValidId(id: unknown): id is string | number | null | undefined {\n return (\n id === undefined ||\n id === null ||\n typeof id === \"string\" ||\n typeof id === \"number\"\n );\n}\n\n// Exported for unit tests so the line-handling logic is exercised\n// independently of process.stdin / process.stdout.\nexport async function processLine(\n line: string,\n handler: RequestHandler,\n writeOut: (response: JsonRpcResponse) => void,\n writeErr: (msg: string) => void = (msg) => process.stderr.write(msg),\n): Promise<void> {\n const trimmed = line.trim();\n if (!trimmed) return;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n writeOut({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32700, message: \"Parse error\" },\n });\n return;\n }\n\n const request = parsed as JsonRpcRequest;\n const rawId = (request as { id?: unknown } | null)?.id;\n\n // Invalid request shape (missing/wrong jsonrpc, non-string method).\n if (\n !request ||\n typeof request !== \"object\" ||\n request.jsonrpc !== \"2.0\" ||\n typeof request.method !== \"string\"\n ) {\n // Echo the id back only if it's a valid string/number. Notifications\n // (missing/null id) and malformed ids both drop silently — we don't\n // want to respond to something that could be a notification, and we\n // can't invent an id for a malformed one.\n if (typeof rawId === \"string\" || typeof rawId === \"number\") {\n writeOut({\n jsonrpc: \"2.0\",\n id: rawId,\n error: { code: -32600, message: \"Invalid Request\" },\n });\n }\n return;\n }\n\n // Request shape is valid but id may still be of the wrong type\n // (object, array, boolean). Per the spec, that's an Invalid Request.\n // Respond with id: null because we can't safely echo a non-JSON-RPC id.\n if (!isValidId(rawId)) {\n writeOut({\n jsonrpc: \"2.0\",\n id: null,\n error: { code: -32600, message: \"Invalid Request: id must be string, number, or null\" },\n });\n return;\n }\n\n const notification = isNotification(request);\n\n try {\n const result = await handler(request.method, request.params || {});\n if (notification) return;\n writeOut({\n jsonrpc: \"2.0\",\n id: request.id as string | number,\n result,\n });\n } catch (err) {\n if (notification) {\n writeErr(\n `[mcp-transport] notification handler error for ${request.method}: ${\n err instanceof Error ? err.message : String(err)\n }\\n`,\n );\n return;\n }\n writeOut({\n jsonrpc: \"2.0\",\n id: request.id as string | number,\n error: {\n code: -32603,\n message: err instanceof Error ? err.message : String(err),\n },\n });\n }\n}\n\nexport function createStdioTransport(handler: RequestHandler): {\n start: () => void;\n stop: () => void;\n} {\n let rl: ReturnType<typeof createInterface> | null = null;\n\n const writeResponse = (response: JsonRpcResponse) => {\n process.stdout.write(JSON.stringify(response) + \"\\n\");\n };\n\n const onLine = (line: string) => processLine(line, handler, writeResponse);\n\n return {\n start() {\n rl = createInterface({ input: process.stdin });\n rl.on(\"line\", onLine);\n },\n stop() {\n rl?.close();\n rl = null;\n },\n };\n}\n","#!/usr/bin/env node\n\nimport { InMemoryKV } from \"./in-memory-kv.js\";\nimport { createStdioTransport } from \"./transport.js\";\nimport { getVisibleTools } from \"./tools-registry.js\";\nimport { getStandalonePersistPath } from \"../config.js\";\nimport { VERSION } from \"../version.js\";\nimport { generateId } from \"../state/schema.js\";\n\nconst IMPLEMENTED_TOOLS = new Set([\n \"memory_save\",\n \"memory_recall\",\n \"memory_sessions\",\n \"memory_export\",\n \"memory_audit\",\n]);\n\nconst SERVER_INFO = {\n name: \"agentmemory\",\n version: VERSION,\n protocolVersion: \"2024-11-05\",\n};\n\nconst kv = new InMemoryKV(getStandalonePersistPath());\n\nexport async function handleToolCall(\n toolName: string,\n args: Record<string, unknown>,\n kvInstance: InMemoryKV = kv,\n): Promise<{ content: Array<{ type: string; text: string }> }> {\n switch (toolName) {\n case \"memory_save\": {\n const content = args.content as string;\n if (!content?.trim()) throw new Error(\"content is required\");\n const id = generateId(\"mem\");\n const isoNow = new Date().toISOString();\n await kvInstance.set(\"mem:memories\", id, {\n id,\n type: (args.type as string) || \"fact\",\n title: content.slice(0, 80),\n content,\n concepts: args.concepts\n ? (args.concepts as string).split(\",\").map((c) => c.trim())\n : [],\n files: args.files\n ? (args.files as string).split(\",\").map((f) => f.trim())\n : [],\n createdAt: isoNow,\n updatedAt: isoNow,\n strength: 7,\n version: 1,\n isLatest: true,\n sessionIds: [],\n });\n kvInstance.persist();\n return {\n content: [{ type: \"text\", text: JSON.stringify({ saved: id }) }],\n };\n }\n\n case \"memory_recall\": {\n const query = (args.query as string)?.toLowerCase() || \"\";\n const limit = (args.limit as number) || 10;\n const all = await kvInstance.list<Record<string, unknown>>(\"mem:memories\");\n const results = all\n .filter((m) => {\n const text = `${m.title} ${m.content}`.toLowerCase();\n return text.includes(query);\n })\n .slice(0, limit);\n return {\n content: [{ type: \"text\", text: JSON.stringify(results, null, 2) }],\n };\n }\n\n case \"memory_sessions\": {\n const sessions = await kvInstance.list(\"mem:sessions\");\n return {\n content: [\n { type: \"text\", text: JSON.stringify({ sessions }, null, 2) },\n ],\n };\n }\n\n case \"memory_export\": {\n const memories = await kvInstance.list(\"mem:memories\");\n const sessions = await kvInstance.list(\"mem:sessions\");\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n { version: VERSION, memories, sessions },\n null,\n 2,\n ),\n },\n ],\n };\n }\n\n case \"memory_audit\": {\n const entries = await kvInstance.list(\"mem:audit\");\n const limit = (args.limit as number) || 50;\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(\n (entries as Array<Record<string, unknown>>).slice(0, limit),\n null,\n 2,\n ),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${toolName}`);\n }\n}\n\nconst transport = createStdioTransport(async (method, params) => {\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: SERVER_INFO.protocolVersion,\n capabilities: {\n tools: { listChanged: false },\n },\n serverInfo: {\n name: SERVER_INFO.name,\n version: SERVER_INFO.version,\n },\n };\n\n case \"notifications/initialized\":\n return {};\n\n case \"tools/list\":\n return {\n tools: getVisibleTools().filter((t) => IMPLEMENTED_TOOLS.has(t.name)),\n };\n\n case \"tools/call\": {\n const toolName = params.name as string;\n const toolArgs = (params.arguments as Record<string, unknown>) || {};\n try {\n return await handleToolCall(toolName, toolArgs);\n } catch (err) {\n return {\n content: [\n {\n type: \"text\",\n text: `Error: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n isError: true,\n };\n }\n }\n\n default:\n throw new Error(`Unknown method: ${method}`);\n }\n});\n\nprocess.stderr.write(\n `[agentmemory-mcp] Standalone MCP server v${SERVER_INFO.version} starting...\\n`,\n);\ntransport.start();\n\nprocess.on(\"SIGINT\", () => {\n kv.persist();\n process.exit(0);\n});\nprocess.on(\"SIGTERM\", () => {\n kv.persist();\n process.exit(0);\n});\n"],"mappings":"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"}
|
package/dist/standalone.d.mts
CHANGED
|
@@ -1 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/mcp/in-memory-kv.d.ts
|
|
2
|
+
declare class InMemoryKV {
|
|
3
|
+
private persistPath?;
|
|
4
|
+
private store;
|
|
5
|
+
constructor(persistPath?: string | undefined);
|
|
6
|
+
get<T = unknown>(scope: string, key: string): Promise<T | null>;
|
|
7
|
+
set<T = unknown>(scope: string, key: string, data: T): Promise<T>;
|
|
8
|
+
delete(scope: string, key: string): Promise<void>;
|
|
9
|
+
list<T = unknown>(scope: string): Promise<T[]>;
|
|
10
|
+
persist(): void;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/mcp/standalone.d.ts
|
|
14
|
+
declare function handleToolCall(toolName: string, args: Record<string, unknown>, kvInstance?: InMemoryKV): Promise<{
|
|
15
|
+
content: Array<{
|
|
16
|
+
type: string;
|
|
17
|
+
text: string;
|
|
18
|
+
}>;
|
|
19
|
+
}>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { handleToolCall };
|
|
22
|
+
//# sourceMappingURL=standalone.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone.d.mts","names":[],"sources":["../src/mcp/in-memory-kv.ts","../src/mcp/standalone.ts"],"mappings":";cAGa,UAAA;EAAA,QAGS,WAAA;EAAA,QAFZ,KAAA;cAEY,WAAA;EAmBd,GAAA,aAAA,CAAiB,KAAA,UAAe,GAAA,WAAc,OAAA,CAAQ,CAAA;EAItD,GAAA,aAAA,CAAiB,KAAA,UAAe,GAAA,UAAa,IAAA,EAAM,CAAA,GAAI,OAAA,CAAQ,CAAA;EAM/D,MAAA,CAAO,KAAA,UAAe,GAAA,WAAc,OAAA;EAIpC,IAAA,aAAA,CAAkB,KAAA,WAAgB,OAAA,CAAQ,CAAA;EAKhD,OAAA,CAAA;AAAA;;;iBCnBoB,cAAA,CACpB,QAAA,UACA,IAAA,EAAM,MAAA,mBACN,UAAA,GAAY,UAAA,GACX,OAAA;EAAU,OAAA,EAAS,KAAA;IAAQ,IAAA;IAAc,IAAA;EAAA;AAAA"}
|
package/dist/standalone.mjs
CHANGED
|
@@ -49,58 +49,83 @@ var InMemoryKV = class {
|
|
|
49
49
|
|
|
50
50
|
//#endregion
|
|
51
51
|
//#region src/mcp/transport.ts
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
52
|
+
function isNotification(req) {
|
|
53
|
+
return req.id === void 0 || req.id === null;
|
|
54
|
+
}
|
|
55
|
+
function isValidId(id) {
|
|
56
|
+
return id === void 0 || id === null || typeof id === "string" || typeof id === "number";
|
|
57
|
+
}
|
|
58
|
+
async function processLine(line, handler, writeOut, writeErr = (msg) => process.stderr.write(msg)) {
|
|
59
|
+
const trimmed = line.trim();
|
|
60
|
+
if (!trimmed) return;
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(trimmed);
|
|
64
|
+
} catch {
|
|
65
|
+
writeOut({
|
|
66
|
+
jsonrpc: "2.0",
|
|
67
|
+
id: null,
|
|
68
|
+
error: {
|
|
69
|
+
code: -32700,
|
|
70
|
+
message: "Parse error"
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const request = parsed;
|
|
76
|
+
const rawId = request?.id;
|
|
77
|
+
if (!request || typeof request !== "object" || request.jsonrpc !== "2.0" || typeof request.method !== "string") {
|
|
78
|
+
if (typeof rawId === "string" || typeof rawId === "number") writeOut({
|
|
79
|
+
jsonrpc: "2.0",
|
|
80
|
+
id: rawId,
|
|
81
|
+
error: {
|
|
82
|
+
code: -32600,
|
|
83
|
+
message: "Invalid Request"
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (!isValidId(rawId)) {
|
|
89
|
+
writeOut({
|
|
90
|
+
jsonrpc: "2.0",
|
|
91
|
+
id: null,
|
|
92
|
+
error: {
|
|
93
|
+
code: -32600,
|
|
94
|
+
message: "Invalid Request: id must be string, number, or null"
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const notification = isNotification(request);
|
|
100
|
+
try {
|
|
101
|
+
const result = await handler(request.method, request.params || {});
|
|
102
|
+
if (notification) return;
|
|
103
|
+
writeOut({
|
|
104
|
+
jsonrpc: "2.0",
|
|
105
|
+
id: request.id,
|
|
106
|
+
result
|
|
107
|
+
});
|
|
108
|
+
} catch (err) {
|
|
109
|
+
if (notification) {
|
|
110
|
+
writeErr(`[mcp-transport] notification handler error for ${request.method}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
82
111
|
return;
|
|
83
112
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
message: err instanceof Error ? err.message : String(err)
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
process.stdout.write(JSON.stringify(response) + "\n");
|
|
102
|
-
}
|
|
113
|
+
writeOut({
|
|
114
|
+
jsonrpc: "2.0",
|
|
115
|
+
id: request.id,
|
|
116
|
+
error: {
|
|
117
|
+
code: -32603,
|
|
118
|
+
message: err instanceof Error ? err.message : String(err)
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function createStdioTransport(handler) {
|
|
124
|
+
let rl = null;
|
|
125
|
+
const writeResponse = (response) => {
|
|
126
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
103
127
|
};
|
|
128
|
+
const onLine = (line) => processLine(line, handler, writeResponse);
|
|
104
129
|
return {
|
|
105
130
|
start() {
|
|
106
131
|
rl = createInterface({ input: process.stdin });
|
|
@@ -1065,7 +1090,13 @@ function getStandalonePersistPath() {
|
|
|
1065
1090
|
|
|
1066
1091
|
//#endregion
|
|
1067
1092
|
//#region src/version.ts
|
|
1068
|
-
const VERSION = "0.8.
|
|
1093
|
+
const VERSION = "0.8.5";
|
|
1094
|
+
|
|
1095
|
+
//#endregion
|
|
1096
|
+
//#region src/state/schema.ts
|
|
1097
|
+
function generateId(prefix) {
|
|
1098
|
+
return `${prefix}_${Date.now().toString(36)}_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}`;
|
|
1099
|
+
}
|
|
1069
1100
|
|
|
1070
1101
|
//#endregion
|
|
1071
1102
|
//#region src/mcp/standalone.ts
|
|
@@ -1082,26 +1113,28 @@ const SERVER_INFO = {
|
|
|
1082
1113
|
protocolVersion: "2024-11-05"
|
|
1083
1114
|
};
|
|
1084
1115
|
const kv = new InMemoryKV(getStandalonePersistPath());
|
|
1085
|
-
async function handleToolCall(toolName, args) {
|
|
1116
|
+
async function handleToolCall(toolName, args, kvInstance = kv) {
|
|
1086
1117
|
switch (toolName) {
|
|
1087
1118
|
case "memory_save": {
|
|
1088
1119
|
const content = args.content;
|
|
1089
1120
|
if (!content?.trim()) throw new Error("content is required");
|
|
1090
|
-
const id =
|
|
1091
|
-
|
|
1121
|
+
const id = generateId("mem");
|
|
1122
|
+
const isoNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
1123
|
+
await kvInstance.set("mem:memories", id, {
|
|
1092
1124
|
id,
|
|
1093
1125
|
type: args.type || "fact",
|
|
1094
1126
|
title: content.slice(0, 80),
|
|
1095
1127
|
content,
|
|
1096
1128
|
concepts: args.concepts ? args.concepts.split(",").map((c) => c.trim()) : [],
|
|
1097
1129
|
files: args.files ? args.files.split(",").map((f) => f.trim()) : [],
|
|
1098
|
-
createdAt:
|
|
1099
|
-
updatedAt:
|
|
1130
|
+
createdAt: isoNow,
|
|
1131
|
+
updatedAt: isoNow,
|
|
1100
1132
|
strength: 7,
|
|
1101
1133
|
version: 1,
|
|
1102
1134
|
isLatest: true,
|
|
1103
1135
|
sessionIds: []
|
|
1104
1136
|
});
|
|
1137
|
+
kvInstance.persist();
|
|
1105
1138
|
return { content: [{
|
|
1106
1139
|
type: "text",
|
|
1107
1140
|
text: JSON.stringify({ saved: id })
|
|
@@ -1110,7 +1143,7 @@ async function handleToolCall(toolName, args) {
|
|
|
1110
1143
|
case "memory_recall": {
|
|
1111
1144
|
const query = args.query?.toLowerCase() || "";
|
|
1112
1145
|
const limit = args.limit || 10;
|
|
1113
|
-
const results = (await
|
|
1146
|
+
const results = (await kvInstance.list("mem:memories")).filter((m) => {
|
|
1114
1147
|
return `${m.title} ${m.content}`.toLowerCase().includes(query);
|
|
1115
1148
|
}).slice(0, limit);
|
|
1116
1149
|
return { content: [{
|
|
@@ -1119,15 +1152,15 @@ async function handleToolCall(toolName, args) {
|
|
|
1119
1152
|
}] };
|
|
1120
1153
|
}
|
|
1121
1154
|
case "memory_sessions": {
|
|
1122
|
-
const sessions = await
|
|
1155
|
+
const sessions = await kvInstance.list("mem:sessions");
|
|
1123
1156
|
return { content: [{
|
|
1124
1157
|
type: "text",
|
|
1125
1158
|
text: JSON.stringify({ sessions }, null, 2)
|
|
1126
1159
|
}] };
|
|
1127
1160
|
}
|
|
1128
1161
|
case "memory_export": {
|
|
1129
|
-
const memories = await
|
|
1130
|
-
const sessions = await
|
|
1162
|
+
const memories = await kvInstance.list("mem:memories");
|
|
1163
|
+
const sessions = await kvInstance.list("mem:sessions");
|
|
1131
1164
|
return { content: [{
|
|
1132
1165
|
type: "text",
|
|
1133
1166
|
text: JSON.stringify({
|
|
@@ -1138,7 +1171,7 @@ async function handleToolCall(toolName, args) {
|
|
|
1138
1171
|
}] };
|
|
1139
1172
|
}
|
|
1140
1173
|
case "memory_audit": {
|
|
1141
|
-
const entries = await
|
|
1174
|
+
const entries = await kvInstance.list("mem:audit");
|
|
1142
1175
|
const limit = args.limit || 50;
|
|
1143
1176
|
return { content: [{
|
|
1144
1177
|
type: "text",
|
|
@@ -1190,5 +1223,5 @@ process.on("SIGTERM", () => {
|
|
|
1190
1223
|
});
|
|
1191
1224
|
|
|
1192
1225
|
//#endregion
|
|
1193
|
-
export {
|
|
1226
|
+
export { handleToolCall };
|
|
1194
1227
|
//# sourceMappingURL=standalone.mjs.map
|