@rigour-labs/mcp 6.6.0 → 6.6.1
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 +2 -0
- package/dist/index.js +3 -3
- package/dist/tools/memory-handlers.js +5 -1
- package/dist/tools/review-handler.js +11 -1
- package/dist/utils/config.d.ts +9 -0
- package/dist/utils/config.js +18 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -132,6 +132,8 @@ No global install: npx fetches the server when your agent starts it. Keep a vers
|
|
|
132
132
|
|
|
133
133
|
Only Rigour's core tools are listed by default; add `"RIGOUR_MCP_TOOLS": "governance,telemetry"` (or `"full"`) to `env` for the rest. Node.js 22 or later is required.
|
|
134
134
|
|
|
135
|
+
To keep a server apart from your other work (one per employer or client), add `"RIGOUR_USER_MEMORY": "off"`: it then never reads or writes the memories you keep for all your repositories.
|
|
136
|
+
|
|
135
137
|
---
|
|
136
138
|
|
|
137
139
|
## 📖 Documentation
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema
|
|
|
15
15
|
import { randomUUID } from "crypto";
|
|
16
16
|
import { GateRunner, countUsage, flushDailyUsage } from "@rigour-labs/core";
|
|
17
17
|
// Utils
|
|
18
|
-
import { loadConfig, loadMcpSettings, logStudioEvent } from './utils/config.js';
|
|
18
|
+
import { loadConfig, loadMcpSettings, logStudioEvent, resolveCwd } from './utils/config.js';
|
|
19
19
|
import { bindServer } from './utils/notifications.js';
|
|
20
20
|
import { getMcpVersion } from './utils/package-version.js';
|
|
21
21
|
import { buildMcpResultMeta, buildStudioImpact } from './utils/impact-receipt.js';
|
|
@@ -85,7 +85,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
85
85
|
// ─── Tool Dispatch ────────────────────────────────────────────────
|
|
86
86
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
87
87
|
const { name, arguments: args } = request.params;
|
|
88
|
-
const cwd = args
|
|
88
|
+
const cwd = resolveCwd(args);
|
|
89
89
|
const requestId = randomUUID();
|
|
90
90
|
try {
|
|
91
91
|
await logStudioEvent(cwd, { type: "tool_call", requestId, tool: name, arguments: args });
|
|
@@ -369,7 +369,7 @@ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
|
369
369
|
}));
|
|
370
370
|
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
371
371
|
const { name, arguments: promptArgs } = request.params;
|
|
372
|
-
const cwd = promptArgs
|
|
372
|
+
const cwd = resolveCwd(promptArgs);
|
|
373
373
|
const mcpSettings = await loadMcpSettings(cwd);
|
|
374
374
|
const deepMode = mcpSettings.deep_default_mode;
|
|
375
375
|
const prompt = PROMPT_DEFINITIONS.find((p) => p.name === name);
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @since v2.17.0 — extracted from monolithic index.ts
|
|
15
15
|
* @since v4.2.0 — DLP gate on memory persistence
|
|
16
16
|
*/
|
|
17
|
-
import { loadMemory, saveMemory } from '../utils/config.js';
|
|
17
|
+
import { loadMemory, saveMemory, USER_MEMORY_OFF, userMemoryEnabled } from '../utils/config.js';
|
|
18
18
|
import { scanInputForCredentials, formatDLPAlert, createDLPAuditEntry, loadTeamConfiguration, shareMemoryLesson, } from '@rigour-labs/core';
|
|
19
19
|
import { loadPatternIndex, getDefaultIndexPath, } from '@rigour-labs/core/pattern-index';
|
|
20
20
|
import { buildTelemetryMeta } from '../utils/context-telemetry.js';
|
|
@@ -95,6 +95,8 @@ export async function handleRemember(cwd, key, value, scope = 'repo') {
|
|
|
95
95
|
}],
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
+
if (scope === 'user' && !userMemoryEnabled())
|
|
99
|
+
return { content: [{ type: "text", text: `MEMORY NOT STORED: ${USER_MEMORY_OFF}` }] };
|
|
98
100
|
// ── DLP Gate: deep-scan key + value (including JSON interiors) ──
|
|
99
101
|
const textToScan = deepScanValue(key, value);
|
|
100
102
|
const dlpResult = scanInputForCredentials(textToScan);
|
|
@@ -148,6 +150,8 @@ async function shareWithTeam(cwd, key, value) {
|
|
|
148
150
|
return '\nShared with your team as a candidate. Teammates\' agents receive it once someone shares it from Studio (How it learns).';
|
|
149
151
|
}
|
|
150
152
|
export async function handleForget(cwd, key, scope = 'repo') {
|
|
153
|
+
if (scope === 'user' && !userMemoryEnabled())
|
|
154
|
+
return { content: [{ type: "text", text: `NOTHING FORGOTTEN: ${USER_MEMORY_OFF}` }] };
|
|
151
155
|
const store = await loadMemory(cwd, scope);
|
|
152
156
|
if (!store.memories[key]) {
|
|
153
157
|
return { content: [{ type: "text", text: `NO MEMORY FOUND for key "${key}" in ${scope} memory. Nothing to forget.` }] };
|
|
@@ -5,8 +5,17 @@
|
|
|
5
5
|
* With no diff, the change is taken from git: uncommitted work (what the
|
|
6
6
|
* agent just wrote, new files included), or the branch against `base`.
|
|
7
7
|
*/
|
|
8
|
-
import { acknowledgeReview, buildReviewTask, diffFromGit, recordFixLessons, recordLessonsServed, recordReviewOutcome, reviewChange, toReviewFinding } from "@rigour-labs/core";
|
|
8
|
+
import { acknowledgeReview, buildQualityReceipt, buildReviewTask, receiptReport, diffFromGit, recordFixLessons, recordLessonsServed, recordReviewOutcome, reviewChange, toReviewFinding } from "@rigour-labs/core";
|
|
9
9
|
import { notifyProgress } from '../utils/notifications.js';
|
|
10
|
+
/** What is known about each changed function before a model looks; never fails the review. */
|
|
11
|
+
function qualityReceipt(config, cwd, diff) {
|
|
12
|
+
try {
|
|
13
|
+
return { quality_receipt: receiptReport(buildQualityReceipt(cwd, diff, { policy: config.gates.deep?.router, lessonMode: config.gates.deep?.review_lessons })) };
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
10
19
|
export async function handleReview(config, cwd, args) {
|
|
11
20
|
notifyProgress("info", args.diff ? "Reviewing the provided diff..." : `Reviewing ${args.base ? `this branch against ${args.base}` : "uncommitted changes"}...`);
|
|
12
21
|
try {
|
|
@@ -32,6 +41,7 @@ export async function handleReview(config, cwd, args) {
|
|
|
32
41
|
excluded_outside_changed_lines: result.excludedOutsideChangedLines,
|
|
33
42
|
unlocated_failures: result.unlocated,
|
|
34
43
|
gate_errors: result.gateErrors,
|
|
44
|
+
...qualityReceipt(config, cwd, diff),
|
|
35
45
|
...(task ? { review_task: { items: task.items, already_reviewed: task.alreadyReviewed, team_lessons: task.lessons, repo_rules: task.rules, instructions: task.instructions } } : {}),
|
|
36
46
|
next_step: nextStep(result.findings.length, task?.items.length ?? 0),
|
|
37
47
|
});
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -295,6 +295,15 @@ export interface MemoryStore {
|
|
|
295
295
|
}
|
|
296
296
|
/** The home whose .rigour/ holds user-scope memory: RIGOUR_HOME when set (tests, sandboxes), else the OS home. */
|
|
297
297
|
export declare function userHome(): string;
|
|
298
|
+
/**
|
|
299
|
+
* False when RIGOUR_USER_MEMORY=off. A server kept apart from the user's other work (a private
|
|
300
|
+
* HOME per employer, a sandbox) then never reads or writes ~/.rigour/memory.json, even if it is
|
|
301
|
+
* started with the real home by mistake.
|
|
302
|
+
*/
|
|
303
|
+
export declare function userMemoryEnabled(): boolean;
|
|
304
|
+
export declare const USER_MEMORY_OFF = "User memory is off on this server (RIGOUR_USER_MEMORY=off); use scope \"repo\".";
|
|
305
|
+
/** The repository a call works in: the call's own cwd, else RIGOUR_CWD, else where the server was started. */
|
|
306
|
+
export declare function resolveCwd(args: unknown): string;
|
|
298
307
|
/** Where memories live: `repo` in this checkout's .rigour/, `user` in ~/.rigour/ for every repository. */
|
|
299
308
|
export type LocalMemoryScope = 'repo' | 'user';
|
|
300
309
|
export declare function getMemoryPath(cwd: string, scope?: LocalMemoryScope): Promise<string>;
|
package/dist/utils/config.js
CHANGED
|
@@ -38,12 +38,28 @@ function noteMissingConfig(cwd) {
|
|
|
38
38
|
export function userHome() {
|
|
39
39
|
return process.env.RIGOUR_HOME || os.homedir();
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* False when RIGOUR_USER_MEMORY=off. A server kept apart from the user's other work (a private
|
|
43
|
+
* HOME per employer, a sandbox) then never reads or writes ~/.rigour/memory.json, even if it is
|
|
44
|
+
* started with the real home by mistake.
|
|
45
|
+
*/
|
|
46
|
+
export function userMemoryEnabled() {
|
|
47
|
+
return process.env.RIGOUR_USER_MEMORY?.trim().toLowerCase() !== 'off';
|
|
48
|
+
}
|
|
49
|
+
export const USER_MEMORY_OFF = 'User memory is off on this server (RIGOUR_USER_MEMORY=off); use scope "repo".';
|
|
50
|
+
/** The repository a call works in: the call's own cwd, else RIGOUR_CWD, else where the server was started. */
|
|
51
|
+
export function resolveCwd(args) {
|
|
52
|
+
const given = args?.cwd;
|
|
53
|
+
return typeof given === 'string' && given ? given : process.env.RIGOUR_CWD || process.cwd();
|
|
54
|
+
}
|
|
41
55
|
export async function getMemoryPath(cwd, scope = 'repo') {
|
|
42
56
|
const rigourDir = scope === 'user' ? path.join(userHome(), ".rigour") : path.join(cwd, ".rigour");
|
|
43
57
|
await fs.ensureDir(rigourDir);
|
|
44
58
|
return path.join(rigourDir, "memory.json");
|
|
45
59
|
}
|
|
46
60
|
export async function loadMemory(cwd, scope = 'repo') {
|
|
61
|
+
if (scope === 'user' && !userMemoryEnabled())
|
|
62
|
+
return { memories: {} };
|
|
47
63
|
const memPath = await getMemoryPath(cwd, scope);
|
|
48
64
|
if (await fs.pathExists(memPath)) {
|
|
49
65
|
const content = await fs.readFile(memPath, "utf-8");
|
|
@@ -60,6 +76,8 @@ export async function loadMemory(cwd, scope = 'repo') {
|
|
|
60
76
|
return { memories: {} };
|
|
61
77
|
}
|
|
62
78
|
export async function saveMemory(cwd, store, scope = 'repo') {
|
|
79
|
+
if (scope === 'user' && !userMemoryEnabled())
|
|
80
|
+
throw new Error(USER_MEMORY_OFF);
|
|
63
81
|
const memPath = await getMemoryPath(cwd, scope);
|
|
64
82
|
await fs.writeFile(memPath, JSON.stringify(store, null, 2));
|
|
65
83
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/mcp",
|
|
3
|
-
"version": "6.6.
|
|
3
|
+
"version": "6.6.1",
|
|
4
4
|
"description": "MCP server + live dashboard for AI code governance — OWASP LLM Top 10 (10/10), real-time MCP App UI, 25+ security patterns, memory and lessons recalled by meaning, hallucinated import detection, multi-agent governance. Works with Claude, Cursor, VS Code, ChatGPT, Goose, Windsurf. Industry presets for HIPAA, SOC2, FedRAMP.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"execa": "^8.0.1",
|
|
66
66
|
"fs-extra": "^11.4.0",
|
|
67
67
|
"yaml": "^2.8.2",
|
|
68
|
-
"@rigour-labs/core": "6.6.
|
|
68
|
+
"@rigour-labs/core": "6.6.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.0.3",
|