@drqedwards/pmll 2.0.4
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/LICENSE +21 -0
- package/README.md +26 -0
- package/agent_instructions.md +123 -0
- package/benchmarks/benchmark_retrieval.md +94 -0
- package/benchmarks/contextplus-standalone-speed.md +185 -0
- package/benchmarks/run_retrieval_stub.py +343 -0
- package/benchmarks/speed-test-results.md +163 -0
- package/benchmarks/three-way-speed-comparison.md +238 -0
- package/dist/embeddings.d.ts +32 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +140 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/graphql.d.ts +81 -0
- package/dist/graphql.d.ts.map +1 -0
- package/dist/graphql.js +389 -0
- package/dist/graphql.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +645 -0
- package/dist/index.js.map +1 -0
- package/dist/kv-store.d.ts +32 -0
- package/dist/kv-store.d.ts.map +1 -0
- package/dist/kv-store.js +103 -0
- package/dist/kv-store.js.map +1 -0
- package/dist/memory-graph.d.ts +122 -0
- package/dist/memory-graph.d.ts.map +1 -0
- package/dist/memory-graph.js +345 -0
- package/dist/memory-graph.js.map +1 -0
- package/dist/peek.d.ts +67 -0
- package/dist/peek.d.ts.map +1 -0
- package/dist/peek.js +61 -0
- package/dist/peek.js.map +1 -0
- package/dist/q-promise-bridge.d.ts +58 -0
- package/dist/q-promise-bridge.d.ts.map +1 -0
- package/dist/q-promise-bridge.js +88 -0
- package/dist/q-promise-bridge.js.map +1 -0
- package/dist/solution-engine.d.ts +54 -0
- package/dist/solution-engine.d.ts.map +1 -0
- package/dist/solution-engine.js +73 -0
- package/dist/solution-engine.js.map +1 -0
- package/package.json +69 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* index.ts — PMLL Memory MCP Server entrypoint.
|
|
4
|
+
*
|
|
5
|
+
* Exposes 15 MCP tools for Claude Sonnet/Opus agents:
|
|
6
|
+
*
|
|
7
|
+
* Short-term KV memory (5 tools):
|
|
8
|
+
* init — Set up the PMLL memory silo and Q-promise chain for a session.
|
|
9
|
+
* peek — Non-destructive context check (core deduplication primitive).
|
|
10
|
+
* set — Store a KV pair in the session's PMLL silo.
|
|
11
|
+
* resolve — Resolve a pending Q-promise continuation.
|
|
12
|
+
* flush — Clear all short-term KV slots at agent task completion.
|
|
13
|
+
*
|
|
14
|
+
* GraphQL (1 tool):
|
|
15
|
+
* graphql — Execute GraphQL queries/mutations against the memory store.
|
|
16
|
+
*
|
|
17
|
+
* Long-term memory graph (6 tools — adapted from Context+ by @ForLoopCodes):
|
|
18
|
+
* upsert_memory_node — Create/update memory nodes with TF-IDF embeddings.
|
|
19
|
+
* create_relation — Create typed edges between nodes.
|
|
20
|
+
* search_memory_graph — Semantic search with graph traversal.
|
|
21
|
+
* prune_stale_links — Remove decayed edges and orphan nodes.
|
|
22
|
+
* add_interlinked_context — Bulk-add nodes with auto-similarity linking.
|
|
23
|
+
* retrieve_with_traversal — Walk outward from a node.
|
|
24
|
+
*
|
|
25
|
+
* Solution engine (3 tools):
|
|
26
|
+
* resolve_context — Unified short-term → long-term context lookup.
|
|
27
|
+
* promote_to_long_term — Promote KV entries to the memory graph.
|
|
28
|
+
* memory_status — Unified memory view across both layers.
|
|
29
|
+
*
|
|
30
|
+
* The server is designed as the **3rd initializer** alongside Playwright and
|
|
31
|
+
* other MCP tools. Agents call `init` once at task start, then use
|
|
32
|
+
* `peek` before any expensive MCP tool invocation to avoid redundant calls.
|
|
33
|
+
*
|
|
34
|
+
* Context+ integration by @ForLoopCodes (https://github.com/ForLoopCodes/contextplus).
|
|
35
|
+
*
|
|
36
|
+
* Architecture:
|
|
37
|
+
* - KV layer → `PMMemoryStore` (mirrors PMLL.c memory_silo_t)
|
|
38
|
+
* - Async layer → `QPromiseRegistry` (mirrors Q_promise_lib QMemNode chain)
|
|
39
|
+
* - Guard function → `peekContext()` (peek.ts)
|
|
40
|
+
* - Long-term → `memory-graph.ts` (adapted from Context+)
|
|
41
|
+
* - Engine → `solution-engine.ts` (bridges short-term + long-term)
|
|
42
|
+
*
|
|
43
|
+
* Usage:
|
|
44
|
+
* npx pmll-memory-mcp # stdio transport
|
|
45
|
+
* node dist/index.js # via compiled output
|
|
46
|
+
*
|
|
47
|
+
* License: MIT
|
|
48
|
+
*/
|
|
49
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
50
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
51
|
+
import { z } from "zod";
|
|
52
|
+
import { getStore, dropStore, resetStore } from "./kv-store.js";
|
|
53
|
+
import { QPromiseRegistry } from "./q-promise-bridge.js";
|
|
54
|
+
import { peekContext } from "./peek.js";
|
|
55
|
+
import { executeGraphQL, GRAPHQL_QUERY, GRAPHQL_MUTATION, GRAPHQL_DEFAULT_VARIABLES } from "./graphql.js";
|
|
56
|
+
import { upsertNode, createRelation, searchGraph, pruneStaleLinks, addInterlinkedContext, retrieveWithTraversal, getGraphStats, } from "./memory-graph.js";
|
|
57
|
+
import { resolveContext, promoteToLongTerm, getMemoryStatus } from "./solution-engine.js";
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// MCP server instance
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
const server = new McpServer({
|
|
62
|
+
name: "pmll-memory-mcp",
|
|
63
|
+
version: "1.0.0",
|
|
64
|
+
}, {
|
|
65
|
+
instructions: "PMLL Memory MCP — persistent memory logic loop with short-term KV " +
|
|
66
|
+
"context memory, Q-promise deduplication, and Context+ long-term " +
|
|
67
|
+
"semantic memory graph designed to improve context retention and retrieval for coding agents. " +
|
|
68
|
+
"Short-term tools: `init`, `peek`, `set`, `resolve`, `flush`. " +
|
|
69
|
+
"Long-term tools: `upsert_memory_node`, `create_relation`, " +
|
|
70
|
+
"`search_memory_graph`, `prune_stale_links`, `add_interlinked_context`, " +
|
|
71
|
+
"`retrieve_with_traversal`. " +
|
|
72
|
+
"Solution engine: `resolve_context` (unified short+long term lookup), " +
|
|
73
|
+
"`promote_to_long_term` (promote KV entries to graph), " +
|
|
74
|
+
"`memory_status` (unified memory view).",
|
|
75
|
+
});
|
|
76
|
+
// Module-level Q-promise registry shared across all sessions.
|
|
77
|
+
// Mirrors the global QMemNode chain pool in Q_promise_lib.
|
|
78
|
+
export const _promiseRegistry = new QPromiseRegistry();
|
|
79
|
+
// Track which sessions have been initialised (sessionId → siloSize).
|
|
80
|
+
export const _activeSessions = new Map();
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Tool: init
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
server.tool("init", "Initialise the PMLL memory silo for an agent session. " +
|
|
85
|
+
"Call this once at the start of every agent task, as the 3rd " +
|
|
86
|
+
"initializer alongside Playwright. Sets up the KV silo and prepares " +
|
|
87
|
+
"the Q-promise chain for the session.", {
|
|
88
|
+
session_id: z.string().describe("Unique identifier for this agent task (e.g. a UUID)."),
|
|
89
|
+
silo_size: z
|
|
90
|
+
.number()
|
|
91
|
+
.int()
|
|
92
|
+
.positive()
|
|
93
|
+
.default(256)
|
|
94
|
+
.describe("Maximum number of KV slots (mirrors memory_silo_t.size)."),
|
|
95
|
+
}, async ({ session_id, silo_size }) => {
|
|
96
|
+
// clear_on_init: re-initing the same session resets the short-term KV silo.
|
|
97
|
+
resetStore(session_id, silo_size);
|
|
98
|
+
_activeSessions.set(session_id, silo_size);
|
|
99
|
+
return {
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
type: "text",
|
|
103
|
+
text: JSON.stringify({
|
|
104
|
+
status: "initialized",
|
|
105
|
+
session_id,
|
|
106
|
+
silo_size,
|
|
107
|
+
cleared: true,
|
|
108
|
+
}),
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Tool: peek
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
server.tool("peek", "Non-destructive context check — the core deduplication primitive. " +
|
|
117
|
+
"Call this before any Playwright or other MCP tool invocation to " +
|
|
118
|
+
"check whether the required context already exists in the PMLL silo or " +
|
|
119
|
+
"is in-flight as a Q-promise.", {
|
|
120
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
121
|
+
key: z.string().describe("The context key to look up."),
|
|
122
|
+
}, async ({ session_id, key }) => {
|
|
123
|
+
const store = getStore(session_id);
|
|
124
|
+
const result = peekContext(key, session_id, store, _promiseRegistry);
|
|
125
|
+
return {
|
|
126
|
+
content: [
|
|
127
|
+
{
|
|
128
|
+
type: "text",
|
|
129
|
+
text: JSON.stringify(result),
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// Tool: set
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
server.tool("set", "Store a KV pair in the session's PMLL memory silo. " +
|
|
138
|
+
"Call after a successful (non-cached) MCP tool invocation to populate " +
|
|
139
|
+
"the silo so future `peek` calls return a cache hit. " +
|
|
140
|
+
"Mirrors PMLL.c::update_silo() writing a var/value pair into the silo.", {
|
|
141
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
142
|
+
key: z.string().describe("The context key."),
|
|
143
|
+
value: z.string().describe("The string value to cache."),
|
|
144
|
+
}, async ({ session_id, key, value }) => {
|
|
145
|
+
const store = getStore(session_id);
|
|
146
|
+
const index = store.set(key, value);
|
|
147
|
+
return {
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: "text",
|
|
151
|
+
text: JSON.stringify({ status: "stored", index }),
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Tool: resolve
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
server.tool("resolve", "Check or resolve a Q-promise continuation. " +
|
|
160
|
+
"Mirrors the `QThenCallback` mechanism in Q_promise_lib/Q_promises.h — " +
|
|
161
|
+
"the callback is invoked when a QMemNode's payload becomes available. " +
|
|
162
|
+
"If the promise is already resolved, returns its payload immediately. " +
|
|
163
|
+
"If still pending, returns `{status: \"pending\", payload: null}`.", {
|
|
164
|
+
session_id: z
|
|
165
|
+
.string()
|
|
166
|
+
.describe("The session identifier (for context; not used to namespace promises)."),
|
|
167
|
+
promise_id: z.string().describe("The promise identifier previously registered."),
|
|
168
|
+
}, async ({ session_id: _sessionId, promise_id }) => {
|
|
169
|
+
const [found, status, payload] = _promiseRegistry.peekPromise(promise_id);
|
|
170
|
+
let result;
|
|
171
|
+
if (!found) {
|
|
172
|
+
result = { status: "pending", payload: null };
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
result = { status: status, payload };
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
content: [
|
|
179
|
+
{
|
|
180
|
+
type: "text",
|
|
181
|
+
text: JSON.stringify(result),
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
});
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// Tool: flush
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
server.tool("flush", "Clear all short-term KV slots for a session. " +
|
|
190
|
+
"Call at agent task completion to free memory. Mirrors the teardown " +
|
|
191
|
+
"of a memory_silo_t allocation (PMLL.c::free_pml).", {
|
|
192
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
193
|
+
}, async ({ session_id }) => {
|
|
194
|
+
const cleared = dropStore(session_id);
|
|
195
|
+
_activeSessions.delete(session_id);
|
|
196
|
+
return {
|
|
197
|
+
content: [
|
|
198
|
+
{
|
|
199
|
+
type: "text",
|
|
200
|
+
text: JSON.stringify({ status: "flushed", cleared_count: cleared }),
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
// ---------------------------------------------------------------------------
|
|
206
|
+
// Tool: graphql
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
server.tool("graphql", "Execute a GraphQL query or mutation against a remote endpoint, with " +
|
|
209
|
+
"optional PMLL cache integration. " +
|
|
210
|
+
"Supply `operation` as a GraphQL document string and `variables` as a " +
|
|
211
|
+
"JSON object. Pass `cache_key` to store/retrieve the result from the " +
|
|
212
|
+
"PMLL silo so redundant network calls are avoided on subsequent `peek` " +
|
|
213
|
+
"checks. The `operation` defaults to the pre-built canonical Query " +
|
|
214
|
+
"document when omitted. Use `use_mutation` to switch the default to the " +
|
|
215
|
+
"canonical Mutation document.", {
|
|
216
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
217
|
+
endpoint: z.string().url().describe("Full URL of the GraphQL endpoint."),
|
|
218
|
+
operation: z
|
|
219
|
+
.string()
|
|
220
|
+
.optional()
|
|
221
|
+
.describe("GraphQL operation document. Defaults to the canonical Query " +
|
|
222
|
+
"when omitted (or the canonical Mutation when `use_mutation` is true)."),
|
|
223
|
+
variables: z
|
|
224
|
+
.record(z.unknown())
|
|
225
|
+
.optional()
|
|
226
|
+
.default({})
|
|
227
|
+
.describe("Variables to pass with the operation (JSON object)."),
|
|
228
|
+
headers: z
|
|
229
|
+
.record(z.string())
|
|
230
|
+
.optional()
|
|
231
|
+
.default({})
|
|
232
|
+
.describe("Additional HTTP headers, e.g. { Authorization: 'Bearer <token>' }."),
|
|
233
|
+
cache_key: z
|
|
234
|
+
.string()
|
|
235
|
+
.optional()
|
|
236
|
+
.describe("When provided, the result is stored under this key in the PMLL silo. " +
|
|
237
|
+
"A subsequent `peek` with the same key will return the cached value " +
|
|
238
|
+
"without re-executing the operation."),
|
|
239
|
+
use_mutation: z
|
|
240
|
+
.boolean()
|
|
241
|
+
.optional()
|
|
242
|
+
.default(false)
|
|
243
|
+
.describe("When true and `operation` is omitted, use the canonical Mutation " +
|
|
244
|
+
"document instead of the canonical Query document."),
|
|
245
|
+
}, async ({ session_id, endpoint, operation, variables, headers, cache_key, use_mutation }) => {
|
|
246
|
+
const store = getStore(session_id);
|
|
247
|
+
// Check PMLL cache first when a cache key is provided.
|
|
248
|
+
if (cache_key) {
|
|
249
|
+
const cached = peekContext(cache_key, session_id, store, _promiseRegistry);
|
|
250
|
+
if (cached.hit && "value" in cached) {
|
|
251
|
+
let parsedData = cached.value;
|
|
252
|
+
try {
|
|
253
|
+
parsedData = JSON.parse(cached.value);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// Cached value is not JSON; return as a raw string.
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
content: [
|
|
260
|
+
{
|
|
261
|
+
type: "text",
|
|
262
|
+
text: JSON.stringify({ cached: true, data: parsedData }),
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Resolve the operation document.
|
|
269
|
+
const doc = operation ?? (use_mutation ? GRAPHQL_MUTATION : GRAPHQL_QUERY);
|
|
270
|
+
// Merge caller variables on top of the default (all-null) variable set
|
|
271
|
+
// so the operation document receives every declared variable.
|
|
272
|
+
const mergedVariables = {
|
|
273
|
+
...GRAPHQL_DEFAULT_VARIABLES,
|
|
274
|
+
...variables,
|
|
275
|
+
};
|
|
276
|
+
let result;
|
|
277
|
+
try {
|
|
278
|
+
result = await executeGraphQL(endpoint, doc, mergedVariables, headers);
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
282
|
+
return {
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: "text",
|
|
286
|
+
text: JSON.stringify({ error: message }),
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const resultStr = JSON.stringify(result);
|
|
292
|
+
// Populate the PMLL silo so future peek calls return a cache hit.
|
|
293
|
+
if (cache_key) {
|
|
294
|
+
store.set(cache_key, resultStr);
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
content: [
|
|
298
|
+
{
|
|
299
|
+
type: "text",
|
|
300
|
+
text: JSON.stringify({ cached: false, data: result }),
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
};
|
|
304
|
+
});
|
|
305
|
+
// ---------------------------------------------------------------------------
|
|
306
|
+
// Tool: upsert_memory_node (Long-term memory)
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
server.tool("upsert_memory_node", "Create or update a memory node in the long-term semantic graph. " +
|
|
309
|
+
"Nodes represent concepts, files, symbols, or notes with auto-generated " +
|
|
310
|
+
"TF-IDF embeddings for semantic search. Part of the Context+ solution " +
|
|
311
|
+
"engine for durable context retention and retrieval.", {
|
|
312
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
313
|
+
type: z
|
|
314
|
+
.enum(["concept", "file", "symbol", "note"])
|
|
315
|
+
.describe("Node type: concept, file, symbol, or note."),
|
|
316
|
+
label: z.string().describe("Short label for the node."),
|
|
317
|
+
content: z.string().describe("Full content/description of the node."),
|
|
318
|
+
metadata: z
|
|
319
|
+
.record(z.string())
|
|
320
|
+
.optional()
|
|
321
|
+
.default({})
|
|
322
|
+
.describe("Optional key-value metadata for the node."),
|
|
323
|
+
}, async ({ session_id, type, label, content, metadata }) => {
|
|
324
|
+
const node = upsertNode(session_id, type, label, content, metadata);
|
|
325
|
+
const stats = getGraphStats(session_id);
|
|
326
|
+
return {
|
|
327
|
+
content: [
|
|
328
|
+
{
|
|
329
|
+
type: "text",
|
|
330
|
+
text: JSON.stringify({
|
|
331
|
+
status: "upserted",
|
|
332
|
+
node_id: node.id,
|
|
333
|
+
label: node.label,
|
|
334
|
+
node_type: node.type,
|
|
335
|
+
access_count: node.accessCount,
|
|
336
|
+
graph_nodes: stats.nodes,
|
|
337
|
+
graph_edges: stats.edges,
|
|
338
|
+
}),
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
};
|
|
342
|
+
});
|
|
343
|
+
// ---------------------------------------------------------------------------
|
|
344
|
+
// Tool: create_relation (Long-term memory)
|
|
345
|
+
// ---------------------------------------------------------------------------
|
|
346
|
+
server.tool("create_relation", "Create a typed edge between two memory nodes in the long-term graph. " +
|
|
347
|
+
"Supported relation types: relates_to, depends_on, implements, " +
|
|
348
|
+
"references, similar_to, contains.", {
|
|
349
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
350
|
+
source_id: z.string().describe("Source node ID."),
|
|
351
|
+
target_id: z.string().describe("Target node ID."),
|
|
352
|
+
relation: z
|
|
353
|
+
.enum([
|
|
354
|
+
"relates_to",
|
|
355
|
+
"depends_on",
|
|
356
|
+
"implements",
|
|
357
|
+
"references",
|
|
358
|
+
"similar_to",
|
|
359
|
+
"contains",
|
|
360
|
+
])
|
|
361
|
+
.describe("Relation type for the edge."),
|
|
362
|
+
weight: z
|
|
363
|
+
.number()
|
|
364
|
+
.optional()
|
|
365
|
+
.default(1.0)
|
|
366
|
+
.describe("Edge weight (default: 1.0)."),
|
|
367
|
+
}, async ({ session_id, source_id, target_id, relation, weight }) => {
|
|
368
|
+
const edge = createRelation(session_id, source_id, target_id, relation, weight);
|
|
369
|
+
if (!edge) {
|
|
370
|
+
return {
|
|
371
|
+
content: [
|
|
372
|
+
{
|
|
373
|
+
type: "text",
|
|
374
|
+
text: JSON.stringify({
|
|
375
|
+
status: "error",
|
|
376
|
+
message: "One or both node IDs not found",
|
|
377
|
+
}),
|
|
378
|
+
},
|
|
379
|
+
],
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
content: [
|
|
384
|
+
{
|
|
385
|
+
type: "text",
|
|
386
|
+
text: JSON.stringify({
|
|
387
|
+
status: "created",
|
|
388
|
+
edge_id: edge.id,
|
|
389
|
+
relation: edge.relation,
|
|
390
|
+
weight: edge.weight,
|
|
391
|
+
}),
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
};
|
|
395
|
+
});
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
// Tool: search_memory_graph (Long-term memory)
|
|
398
|
+
// ---------------------------------------------------------------------------
|
|
399
|
+
server.tool("search_memory_graph", "Semantic search with graph traversal — finds direct matches then walks " +
|
|
400
|
+
"1st/2nd-degree neighbors. Returns ranked results scored by cosine " +
|
|
401
|
+
"similarity and edge decay.", {
|
|
402
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
403
|
+
query: z.string().describe("Natural language search query."),
|
|
404
|
+
max_depth: z
|
|
405
|
+
.number()
|
|
406
|
+
.int()
|
|
407
|
+
.optional()
|
|
408
|
+
.default(1)
|
|
409
|
+
.describe("Maximum traversal depth (default: 1)."),
|
|
410
|
+
top_k: z
|
|
411
|
+
.number()
|
|
412
|
+
.int()
|
|
413
|
+
.optional()
|
|
414
|
+
.default(5)
|
|
415
|
+
.describe("Maximum number of direct hits (default: 5)."),
|
|
416
|
+
}, async ({ session_id, query, max_depth, top_k }) => {
|
|
417
|
+
const result = searchGraph(session_id, query, max_depth, top_k);
|
|
418
|
+
return {
|
|
419
|
+
content: [
|
|
420
|
+
{
|
|
421
|
+
type: "text",
|
|
422
|
+
text: JSON.stringify({
|
|
423
|
+
query,
|
|
424
|
+
direct: result.direct.map((d) => ({
|
|
425
|
+
node_id: d.node.id,
|
|
426
|
+
label: d.node.label,
|
|
427
|
+
type: d.node.type,
|
|
428
|
+
content: d.node.content,
|
|
429
|
+
score: d.relevanceScore,
|
|
430
|
+
})),
|
|
431
|
+
neighbors: result.neighbors.map((n) => ({
|
|
432
|
+
node_id: n.node.id,
|
|
433
|
+
label: n.node.label,
|
|
434
|
+
type: n.node.type,
|
|
435
|
+
content: n.node.content,
|
|
436
|
+
score: n.relevanceScore,
|
|
437
|
+
depth: n.depth,
|
|
438
|
+
path: n.pathRelations,
|
|
439
|
+
})),
|
|
440
|
+
total_nodes: result.totalNodes,
|
|
441
|
+
total_edges: result.totalEdges,
|
|
442
|
+
}),
|
|
443
|
+
},
|
|
444
|
+
],
|
|
445
|
+
};
|
|
446
|
+
});
|
|
447
|
+
// ---------------------------------------------------------------------------
|
|
448
|
+
// Tool: prune_stale_links (Long-term memory)
|
|
449
|
+
// ---------------------------------------------------------------------------
|
|
450
|
+
server.tool("prune_stale_links", "Remove decayed edges (e^(-λt) below threshold) and orphan nodes with " +
|
|
451
|
+
"low access counts from the long-term memory graph.", {
|
|
452
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
453
|
+
threshold: z
|
|
454
|
+
.number()
|
|
455
|
+
.optional()
|
|
456
|
+
.default(0.15)
|
|
457
|
+
.describe("Decay threshold below which edges are pruned (default: 0.15)."),
|
|
458
|
+
}, async ({ session_id, threshold }) => {
|
|
459
|
+
const result = pruneStaleLinks(session_id, threshold);
|
|
460
|
+
return {
|
|
461
|
+
content: [
|
|
462
|
+
{
|
|
463
|
+
type: "text",
|
|
464
|
+
text: JSON.stringify({
|
|
465
|
+
status: "pruned",
|
|
466
|
+
removed: result.removed,
|
|
467
|
+
remaining_edges: result.remaining,
|
|
468
|
+
}),
|
|
469
|
+
},
|
|
470
|
+
],
|
|
471
|
+
};
|
|
472
|
+
});
|
|
473
|
+
// ---------------------------------------------------------------------------
|
|
474
|
+
// Tool: add_interlinked_context (Long-term memory)
|
|
475
|
+
// ---------------------------------------------------------------------------
|
|
476
|
+
server.tool("add_interlinked_context", "Bulk-add nodes with auto-similarity linking (cosine ≥ 0.72 creates " +
|
|
477
|
+
"edges automatically). Efficient for adding multiple related concepts " +
|
|
478
|
+
"at once.", {
|
|
479
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
480
|
+
items: z
|
|
481
|
+
.array(z.object({
|
|
482
|
+
type: z.enum(["concept", "file", "symbol", "note"]),
|
|
483
|
+
label: z.string(),
|
|
484
|
+
content: z.string(),
|
|
485
|
+
metadata: z.record(z.string()).optional(),
|
|
486
|
+
}))
|
|
487
|
+
.describe("Array of nodes to add."),
|
|
488
|
+
auto_link: z
|
|
489
|
+
.boolean()
|
|
490
|
+
.optional()
|
|
491
|
+
.default(true)
|
|
492
|
+
.describe("Auto-create similarity edges (default: true)."),
|
|
493
|
+
}, async ({ session_id, items, auto_link }) => {
|
|
494
|
+
const result = addInterlinkedContext(session_id, items.map((i) => ({
|
|
495
|
+
type: i.type,
|
|
496
|
+
label: i.label,
|
|
497
|
+
content: i.content,
|
|
498
|
+
metadata: i.metadata,
|
|
499
|
+
})), auto_link);
|
|
500
|
+
return {
|
|
501
|
+
content: [
|
|
502
|
+
{
|
|
503
|
+
type: "text",
|
|
504
|
+
text: JSON.stringify({
|
|
505
|
+
status: "added",
|
|
506
|
+
nodes_created: result.nodes.length,
|
|
507
|
+
edges_created: result.edges.length,
|
|
508
|
+
nodes: result.nodes.map((n) => ({
|
|
509
|
+
id: n.id,
|
|
510
|
+
label: n.label,
|
|
511
|
+
type: n.type,
|
|
512
|
+
})),
|
|
513
|
+
}),
|
|
514
|
+
},
|
|
515
|
+
],
|
|
516
|
+
};
|
|
517
|
+
});
|
|
518
|
+
// ---------------------------------------------------------------------------
|
|
519
|
+
// Tool: retrieve_with_traversal (Long-term memory)
|
|
520
|
+
// ---------------------------------------------------------------------------
|
|
521
|
+
server.tool("retrieve_with_traversal", "Start from a node and walk outward — returns all reachable neighbors " +
|
|
522
|
+
"scored by decay and depth. Used for exploring the knowledge graph " +
|
|
523
|
+
"from a known starting point.", {
|
|
524
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
525
|
+
start_node_id: z.string().describe("ID of the starting node."),
|
|
526
|
+
max_depth: z
|
|
527
|
+
.number()
|
|
528
|
+
.int()
|
|
529
|
+
.optional()
|
|
530
|
+
.default(2)
|
|
531
|
+
.describe("Maximum traversal depth (default: 2)."),
|
|
532
|
+
}, async ({ session_id, start_node_id, max_depth }) => {
|
|
533
|
+
const results = retrieveWithTraversal(session_id, start_node_id, max_depth);
|
|
534
|
+
if (results.length === 0) {
|
|
535
|
+
return {
|
|
536
|
+
content: [
|
|
537
|
+
{
|
|
538
|
+
type: "text",
|
|
539
|
+
text: JSON.stringify({
|
|
540
|
+
status: "error",
|
|
541
|
+
message: `Node not found: ${start_node_id}`,
|
|
542
|
+
}),
|
|
543
|
+
},
|
|
544
|
+
],
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
return {
|
|
548
|
+
content: [
|
|
549
|
+
{
|
|
550
|
+
type: "text",
|
|
551
|
+
text: JSON.stringify({
|
|
552
|
+
start_node: results[0].node.label,
|
|
553
|
+
results: results.map((r) => ({
|
|
554
|
+
node_id: r.node.id,
|
|
555
|
+
label: r.node.label,
|
|
556
|
+
type: r.node.type,
|
|
557
|
+
content: r.node.content,
|
|
558
|
+
depth: r.depth,
|
|
559
|
+
score: r.relevanceScore,
|
|
560
|
+
path: r.pathRelations,
|
|
561
|
+
})),
|
|
562
|
+
}),
|
|
563
|
+
},
|
|
564
|
+
],
|
|
565
|
+
};
|
|
566
|
+
});
|
|
567
|
+
// ---------------------------------------------------------------------------
|
|
568
|
+
// Tool: resolve_context (Solution Engine)
|
|
569
|
+
// ---------------------------------------------------------------------------
|
|
570
|
+
server.tool("resolve_context", "Unified context resolution across both short-term (KV cache) and " +
|
|
571
|
+
"long-term (semantic graph) memory layers. Checks KV cache first, " +
|
|
572
|
+
"then falls back to semantic graph search. This is the primary " +
|
|
573
|
+
"Context+ solution engine tool for unified KV + graph retrieval.", {
|
|
574
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
575
|
+
key: z.string().describe("The context key to resolve."),
|
|
576
|
+
}, async ({ session_id, key }) => {
|
|
577
|
+
const store = getStore(session_id);
|
|
578
|
+
const result = resolveContext(session_id, key, store);
|
|
579
|
+
return {
|
|
580
|
+
content: [
|
|
581
|
+
{
|
|
582
|
+
type: "text",
|
|
583
|
+
text: JSON.stringify(result),
|
|
584
|
+
},
|
|
585
|
+
],
|
|
586
|
+
};
|
|
587
|
+
});
|
|
588
|
+
// ---------------------------------------------------------------------------
|
|
589
|
+
// Tool: promote_to_long_term (Solution Engine)
|
|
590
|
+
// ---------------------------------------------------------------------------
|
|
591
|
+
server.tool("promote_to_long_term", "Promote a short-term KV cache entry to the long-term semantic memory " +
|
|
592
|
+
"graph. Creates a persistent memory node from a frequently accessed " +
|
|
593
|
+
"cache entry, ensuring important context survives session flushes.", {
|
|
594
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
595
|
+
key: z.string().describe("The context key/label for the memory node."),
|
|
596
|
+
value: z.string().describe("The content to store in long-term memory."),
|
|
597
|
+
node_type: z
|
|
598
|
+
.enum(["concept", "file", "symbol", "note"])
|
|
599
|
+
.optional()
|
|
600
|
+
.default("concept")
|
|
601
|
+
.describe("Node type (default: concept)."),
|
|
602
|
+
}, async ({ session_id, key, value, node_type }) => {
|
|
603
|
+
const result = promoteToLongTerm(session_id, key, value, node_type);
|
|
604
|
+
return {
|
|
605
|
+
content: [
|
|
606
|
+
{
|
|
607
|
+
type: "text",
|
|
608
|
+
text: JSON.stringify(result),
|
|
609
|
+
},
|
|
610
|
+
],
|
|
611
|
+
};
|
|
612
|
+
});
|
|
613
|
+
// ---------------------------------------------------------------------------
|
|
614
|
+
// Tool: memory_status (Solution Engine)
|
|
615
|
+
// ---------------------------------------------------------------------------
|
|
616
|
+
server.tool("memory_status", "Get a unified status view of both short-term (KV cache) and long-term " +
|
|
617
|
+
"(semantic graph) memory layers. Shows slot usage, graph statistics, " +
|
|
618
|
+
"and promotion threshold.", {
|
|
619
|
+
session_id: z.string().describe("The session identifier (from `init`)."),
|
|
620
|
+
}, async ({ session_id }) => {
|
|
621
|
+
const store = getStore(session_id);
|
|
622
|
+
const status = getMemoryStatus(session_id, store);
|
|
623
|
+
return {
|
|
624
|
+
content: [
|
|
625
|
+
{
|
|
626
|
+
type: "text",
|
|
627
|
+
text: JSON.stringify(status),
|
|
628
|
+
},
|
|
629
|
+
],
|
|
630
|
+
};
|
|
631
|
+
});
|
|
632
|
+
// ---------------------------------------------------------------------------
|
|
633
|
+
// Entry-point
|
|
634
|
+
// ---------------------------------------------------------------------------
|
|
635
|
+
/** Run the MCP server over stdio (default transport). */
|
|
636
|
+
async function main() {
|
|
637
|
+
const transport = new StdioServerTransport();
|
|
638
|
+
await server.connect(transport);
|
|
639
|
+
}
|
|
640
|
+
main().catch((error) => {
|
|
641
|
+
console.error("Fatal error in MCP server:", error);
|
|
642
|
+
process.exit(1);
|
|
643
|
+
});
|
|
644
|
+
export { server };
|
|
645
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|