@rigour-labs/mcp 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +164 -0
- package/package.json +3 -3
- package/src/index.ts +182 -0
package/dist/index.js
CHANGED
|
@@ -27,6 +27,23 @@ async function loadConfig(cwd) {
|
|
|
27
27
|
const configContent = await fs_extra_1.default.readFile(configPath, "utf-8");
|
|
28
28
|
return core_1.ConfigSchema.parse(yaml_1.default.parse(configContent));
|
|
29
29
|
}
|
|
30
|
+
async function getMemoryPath(cwd) {
|
|
31
|
+
const rigourDir = path_1.default.join(cwd, ".rigour");
|
|
32
|
+
await fs_extra_1.default.ensureDir(rigourDir);
|
|
33
|
+
return path_1.default.join(rigourDir, "memory.json");
|
|
34
|
+
}
|
|
35
|
+
async function loadMemory(cwd) {
|
|
36
|
+
const memPath = await getMemoryPath(cwd);
|
|
37
|
+
if (await fs_extra_1.default.pathExists(memPath)) {
|
|
38
|
+
const content = await fs_extra_1.default.readFile(memPath, "utf-8");
|
|
39
|
+
return JSON.parse(content);
|
|
40
|
+
}
|
|
41
|
+
return { memories: {} };
|
|
42
|
+
}
|
|
43
|
+
async function saveMemory(cwd, store) {
|
|
44
|
+
const memPath = await getMemoryPath(cwd);
|
|
45
|
+
await fs_extra_1.default.writeFile(memPath, JSON.stringify(store, null, 2));
|
|
46
|
+
}
|
|
30
47
|
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
31
48
|
return {
|
|
32
49
|
tools: [
|
|
@@ -114,6 +131,64 @@ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
|
114
131
|
required: ["cwd"],
|
|
115
132
|
},
|
|
116
133
|
},
|
|
134
|
+
{
|
|
135
|
+
name: "rigour_remember",
|
|
136
|
+
description: "Store a persistent instruction or context that the AI should remember across sessions. Use this to persist user preferences, project conventions, or critical instructions.",
|
|
137
|
+
inputSchema: {
|
|
138
|
+
type: "object",
|
|
139
|
+
properties: {
|
|
140
|
+
cwd: {
|
|
141
|
+
type: "string",
|
|
142
|
+
description: "Absolute path to the project root.",
|
|
143
|
+
},
|
|
144
|
+
key: {
|
|
145
|
+
type: "string",
|
|
146
|
+
description: "A unique key for this memory (e.g., 'user_preferences', 'coding_style').",
|
|
147
|
+
},
|
|
148
|
+
value: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "The instruction or context to remember.",
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
required: ["cwd", "key", "value"],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "rigour_recall",
|
|
158
|
+
description: "Retrieve stored instructions or context. Call this at the start of each session to restore memory. Returns all stored memories if no key specified.",
|
|
159
|
+
inputSchema: {
|
|
160
|
+
type: "object",
|
|
161
|
+
properties: {
|
|
162
|
+
cwd: {
|
|
163
|
+
type: "string",
|
|
164
|
+
description: "Absolute path to the project root.",
|
|
165
|
+
},
|
|
166
|
+
key: {
|
|
167
|
+
type: "string",
|
|
168
|
+
description: "Optional. Key of specific memory to retrieve.",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
required: ["cwd"],
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "rigour_forget",
|
|
176
|
+
description: "Remove a stored memory by key.",
|
|
177
|
+
inputSchema: {
|
|
178
|
+
type: "object",
|
|
179
|
+
properties: {
|
|
180
|
+
cwd: {
|
|
181
|
+
type: "string",
|
|
182
|
+
description: "Absolute path to the project root.",
|
|
183
|
+
},
|
|
184
|
+
key: {
|
|
185
|
+
type: "string",
|
|
186
|
+
description: "Key of the memory to remove.",
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
required: ["cwd", "key"],
|
|
190
|
+
},
|
|
191
|
+
},
|
|
117
192
|
],
|
|
118
193
|
};
|
|
119
194
|
});
|
|
@@ -230,6 +305,95 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
|
230
305
|
},
|
|
231
306
|
],
|
|
232
307
|
};
|
|
308
|
+
case "rigour_remember": {
|
|
309
|
+
const { key, value } = args;
|
|
310
|
+
const store = await loadMemory(cwd);
|
|
311
|
+
store.memories[key] = {
|
|
312
|
+
value,
|
|
313
|
+
timestamp: new Date().toISOString(),
|
|
314
|
+
};
|
|
315
|
+
await saveMemory(cwd, store);
|
|
316
|
+
return {
|
|
317
|
+
content: [
|
|
318
|
+
{
|
|
319
|
+
type: "text",
|
|
320
|
+
text: `MEMORY STORED: "${key}" has been saved. This instruction will persist across sessions.\n\nStored value: ${value}`,
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
case "rigour_recall": {
|
|
326
|
+
const { key } = args;
|
|
327
|
+
const store = await loadMemory(cwd);
|
|
328
|
+
if (key) {
|
|
329
|
+
const memory = store.memories[key];
|
|
330
|
+
if (!memory) {
|
|
331
|
+
return {
|
|
332
|
+
content: [
|
|
333
|
+
{
|
|
334
|
+
type: "text",
|
|
335
|
+
text: `NO MEMORY FOUND for key "${key}". Use rigour_remember to store instructions.`,
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
content: [
|
|
342
|
+
{
|
|
343
|
+
type: "text",
|
|
344
|
+
text: `RECALLED MEMORY [${key}]:\n${memory.value}\n\n(Stored: ${memory.timestamp})`,
|
|
345
|
+
},
|
|
346
|
+
],
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
const keys = Object.keys(store.memories);
|
|
350
|
+
if (keys.length === 0) {
|
|
351
|
+
return {
|
|
352
|
+
content: [
|
|
353
|
+
{
|
|
354
|
+
type: "text",
|
|
355
|
+
text: "NO MEMORIES STORED. Use rigour_remember to persist important instructions.",
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const allMemories = keys.map(k => {
|
|
361
|
+
const mem = store.memories[k];
|
|
362
|
+
return `## ${k}\n${mem.value}\n(Stored: ${mem.timestamp})`;
|
|
363
|
+
}).join("\n\n---\n\n");
|
|
364
|
+
return {
|
|
365
|
+
content: [
|
|
366
|
+
{
|
|
367
|
+
type: "text",
|
|
368
|
+
text: `RECALLED ALL MEMORIES (${keys.length} items):\n\n${allMemories}\n\n---\nIMPORTANT: Follow these stored instructions throughout this session.`,
|
|
369
|
+
},
|
|
370
|
+
],
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
case "rigour_forget": {
|
|
374
|
+
const { key } = args;
|
|
375
|
+
const store = await loadMemory(cwd);
|
|
376
|
+
if (!store.memories[key]) {
|
|
377
|
+
return {
|
|
378
|
+
content: [
|
|
379
|
+
{
|
|
380
|
+
type: "text",
|
|
381
|
+
text: `NO MEMORY FOUND for key "${key}". Nothing to forget.`,
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
delete store.memories[key];
|
|
387
|
+
await saveMemory(cwd, store);
|
|
388
|
+
return {
|
|
389
|
+
content: [
|
|
390
|
+
{
|
|
391
|
+
type: "text",
|
|
392
|
+
text: `MEMORY DELETED: "${key}" has been removed.`,
|
|
393
|
+
},
|
|
394
|
+
],
|
|
395
|
+
};
|
|
396
|
+
}
|
|
233
397
|
default:
|
|
234
398
|
throw new Error(`Unknown tool: ${name}`);
|
|
235
399
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"bin": {
|
|
5
5
|
"rigour-mcp": "dist/index.js"
|
|
6
6
|
},
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"provenance": true
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@modelcontextprotocol/sdk": "^
|
|
16
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
17
17
|
"fs-extra": "^11.2.0",
|
|
18
18
|
"yaml": "^2.8.2",
|
|
19
|
-
"@rigour-labs/core": "2.
|
|
19
|
+
"@rigour-labs/core": "2.9.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^25.0.3"
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,31 @@ async function loadConfig(cwd: string) {
|
|
|
31
31
|
return ConfigSchema.parse(yaml.parse(configContent));
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// Memory persistence for context retention
|
|
35
|
+
interface MemoryStore {
|
|
36
|
+
memories: Record<string, { value: string; timestamp: string }>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function getMemoryPath(cwd: string): Promise<string> {
|
|
40
|
+
const rigourDir = path.join(cwd, ".rigour");
|
|
41
|
+
await fs.ensureDir(rigourDir);
|
|
42
|
+
return path.join(rigourDir, "memory.json");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function loadMemory(cwd: string): Promise<MemoryStore> {
|
|
46
|
+
const memPath = await getMemoryPath(cwd);
|
|
47
|
+
if (await fs.pathExists(memPath)) {
|
|
48
|
+
const content = await fs.readFile(memPath, "utf-8");
|
|
49
|
+
return JSON.parse(content);
|
|
50
|
+
}
|
|
51
|
+
return { memories: {} };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function saveMemory(cwd: string, store: MemoryStore): Promise<void> {
|
|
55
|
+
const memPath = await getMemoryPath(cwd);
|
|
56
|
+
await fs.writeFile(memPath, JSON.stringify(store, null, 2));
|
|
57
|
+
}
|
|
58
|
+
|
|
34
59
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
35
60
|
return {
|
|
36
61
|
tools: [
|
|
@@ -118,6 +143,64 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
118
143
|
required: ["cwd"],
|
|
119
144
|
},
|
|
120
145
|
},
|
|
146
|
+
{
|
|
147
|
+
name: "rigour_remember",
|
|
148
|
+
description: "Store a persistent instruction or context that the AI should remember across sessions. Use this to persist user preferences, project conventions, or critical instructions.",
|
|
149
|
+
inputSchema: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {
|
|
152
|
+
cwd: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "Absolute path to the project root.",
|
|
155
|
+
},
|
|
156
|
+
key: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "A unique key for this memory (e.g., 'user_preferences', 'coding_style').",
|
|
159
|
+
},
|
|
160
|
+
value: {
|
|
161
|
+
type: "string",
|
|
162
|
+
description: "The instruction or context to remember.",
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
required: ["cwd", "key", "value"],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "rigour_recall",
|
|
170
|
+
description: "Retrieve stored instructions or context. Call this at the start of each session to restore memory. Returns all stored memories if no key specified.",
|
|
171
|
+
inputSchema: {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {
|
|
174
|
+
cwd: {
|
|
175
|
+
type: "string",
|
|
176
|
+
description: "Absolute path to the project root.",
|
|
177
|
+
},
|
|
178
|
+
key: {
|
|
179
|
+
type: "string",
|
|
180
|
+
description: "Optional. Key of specific memory to retrieve.",
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
required: ["cwd"],
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: "rigour_forget",
|
|
188
|
+
description: "Remove a stored memory by key.",
|
|
189
|
+
inputSchema: {
|
|
190
|
+
type: "object",
|
|
191
|
+
properties: {
|
|
192
|
+
cwd: {
|
|
193
|
+
type: "string",
|
|
194
|
+
description: "Absolute path to the project root.",
|
|
195
|
+
},
|
|
196
|
+
key: {
|
|
197
|
+
type: "string",
|
|
198
|
+
description: "Key of the memory to remove.",
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
required: ["cwd", "key"],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
121
204
|
],
|
|
122
205
|
};
|
|
123
206
|
});
|
|
@@ -247,6 +330,105 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
247
330
|
],
|
|
248
331
|
};
|
|
249
332
|
|
|
333
|
+
case "rigour_remember": {
|
|
334
|
+
const { key, value } = args as any;
|
|
335
|
+
const store = await loadMemory(cwd);
|
|
336
|
+
store.memories[key] = {
|
|
337
|
+
value,
|
|
338
|
+
timestamp: new Date().toISOString(),
|
|
339
|
+
};
|
|
340
|
+
await saveMemory(cwd, store);
|
|
341
|
+
return {
|
|
342
|
+
content: [
|
|
343
|
+
{
|
|
344
|
+
type: "text",
|
|
345
|
+
text: `MEMORY STORED: "${key}" has been saved. This instruction will persist across sessions.\n\nStored value: ${value}`,
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
case "rigour_recall": {
|
|
352
|
+
const { key } = args as any;
|
|
353
|
+
const store = await loadMemory(cwd);
|
|
354
|
+
|
|
355
|
+
if (key) {
|
|
356
|
+
const memory = store.memories[key];
|
|
357
|
+
if (!memory) {
|
|
358
|
+
return {
|
|
359
|
+
content: [
|
|
360
|
+
{
|
|
361
|
+
type: "text",
|
|
362
|
+
text: `NO MEMORY FOUND for key "${key}". Use rigour_remember to store instructions.`,
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
content: [
|
|
369
|
+
{
|
|
370
|
+
type: "text",
|
|
371
|
+
text: `RECALLED MEMORY [${key}]:\n${memory.value}\n\n(Stored: ${memory.timestamp})`,
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const keys = Object.keys(store.memories);
|
|
378
|
+
if (keys.length === 0) {
|
|
379
|
+
return {
|
|
380
|
+
content: [
|
|
381
|
+
{
|
|
382
|
+
type: "text",
|
|
383
|
+
text: "NO MEMORIES STORED. Use rigour_remember to persist important instructions.",
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const allMemories = keys.map(k => {
|
|
390
|
+
const mem = store.memories[k];
|
|
391
|
+
return `## ${k}\n${mem.value}\n(Stored: ${mem.timestamp})`;
|
|
392
|
+
}).join("\n\n---\n\n");
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
content: [
|
|
396
|
+
{
|
|
397
|
+
type: "text",
|
|
398
|
+
text: `RECALLED ALL MEMORIES (${keys.length} items):\n\n${allMemories}\n\n---\nIMPORTANT: Follow these stored instructions throughout this session.`,
|
|
399
|
+
},
|
|
400
|
+
],
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
case "rigour_forget": {
|
|
405
|
+
const { key } = args as any;
|
|
406
|
+
const store = await loadMemory(cwd);
|
|
407
|
+
|
|
408
|
+
if (!store.memories[key]) {
|
|
409
|
+
return {
|
|
410
|
+
content: [
|
|
411
|
+
{
|
|
412
|
+
type: "text",
|
|
413
|
+
text: `NO MEMORY FOUND for key "${key}". Nothing to forget.`,
|
|
414
|
+
},
|
|
415
|
+
],
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
delete store.memories[key];
|
|
420
|
+
await saveMemory(cwd, store);
|
|
421
|
+
|
|
422
|
+
return {
|
|
423
|
+
content: [
|
|
424
|
+
{
|
|
425
|
+
type: "text",
|
|
426
|
+
text: `MEMORY DELETED: "${key}" has been removed.`,
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
250
432
|
default:
|
|
251
433
|
throw new Error(`Unknown tool: ${name}`);
|
|
252
434
|
}
|