@rigour-labs/mcp 5.2.7 → 5.2.9
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
CHANGED
|
@@ -79,6 +79,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
79
79
|
const requestId = randomUUID();
|
|
80
80
|
try {
|
|
81
81
|
await logStudioEvent(cwd, { type: "tool_call", requestId, tool: name, arguments: args });
|
|
82
|
+
// ── Image DLP warning ──────────────────────────────
|
|
83
|
+
// MCP args may contain base64 image data. Text DLP cannot scan images.
|
|
84
|
+
const argsStr = JSON.stringify(args ?? {});
|
|
85
|
+
const hasImageContent = /data:image\/|base64,[A-Za-z0-9+/=]{100,}/.test(argsStr);
|
|
82
86
|
const config = await loadConfig(cwd);
|
|
83
87
|
const runner = new GateRunner(config);
|
|
84
88
|
let result;
|
|
@@ -131,7 +135,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
131
135
|
break;
|
|
132
136
|
// Pattern intelligence
|
|
133
137
|
case "rigour_check_pattern":
|
|
134
|
-
result = await handleCheckPattern(cwd, args.name, args.type, args.intent);
|
|
138
|
+
result = await handleCheckPattern(cwd, args.name, args.type, args.intent, args.file);
|
|
135
139
|
break;
|
|
136
140
|
case "rigour_security_audit":
|
|
137
141
|
result = await handleSecurityAudit(cwd);
|
|
@@ -188,6 +192,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
188
192
|
default:
|
|
189
193
|
throw new Error(`Unknown tool: ${name}`);
|
|
190
194
|
}
|
|
195
|
+
// ── Prepend image DLP warning if image content was detected ──
|
|
196
|
+
if (hasImageContent && Array.isArray(result.content)) {
|
|
197
|
+
result.content.unshift({
|
|
198
|
+
type: "text",
|
|
199
|
+
text: "⚠ DLP Notice: Image content detected in this request. Text-based credential scanning cannot analyze images. Avoid sharing screenshots containing API keys, tokens, or passwords.",
|
|
200
|
+
});
|
|
201
|
+
}
|
|
191
202
|
await logStudioEvent(cwd, {
|
|
192
203
|
type: "tool_response", requestId, tool: name, status: "success",
|
|
193
204
|
content: result.content, _rigour_report: result._rigour_report,
|
|
@@ -231,7 +231,7 @@ export const TOOL_DEFINITIONS = [
|
|
|
231
231
|
// ─── Pattern Intelligence ─────────────────────────────
|
|
232
232
|
{
|
|
233
233
|
name: "rigour_check_pattern",
|
|
234
|
-
description: "CALL THIS BEFORE creating any new function, component, hook, or class. Checks if it already exists in the codebase (prevents duplication),
|
|
234
|
+
description: "CALL THIS BEFORE creating any new function, component, hook, or class. Checks if it already exists in the codebase (prevents duplication), checks for known security vulnerabilities, and BLOCKS writes to protected paths (.github/, CI/CD configs, rigour.yml). Always pass the target file path.",
|
|
235
235
|
inputSchema: {
|
|
236
236
|
type: "object",
|
|
237
237
|
properties: {
|
|
@@ -239,6 +239,7 @@ export const TOOL_DEFINITIONS = [
|
|
|
239
239
|
name: { type: "string", description: "The name of the function, class, or component you want to create." },
|
|
240
240
|
type: { type: "string", description: "The type of pattern (e.g., 'function', 'component', 'hook', 'type')." },
|
|
241
241
|
intent: { type: "string", description: "What the code is for (e.g., 'format dates', 'user authentication')." },
|
|
242
|
+
file: { type: "string", description: "Target file path (relative to cwd) where the code will be written. Used to enforce protected path rules — writes to .github/, rigour.yml, etc. will be BLOCKED." },
|
|
242
243
|
},
|
|
243
244
|
required: ["cwd", "name"],
|
|
244
245
|
},
|
|
@@ -4,6 +4,6 @@ type ToolResult = {
|
|
|
4
4
|
text: string;
|
|
5
5
|
}[];
|
|
6
6
|
};
|
|
7
|
-
export declare function handleCheckPattern(cwd: string, patternName: string, type?: string, intent?: string): Promise<ToolResult>;
|
|
7
|
+
export declare function handleCheckPattern(cwd: string, patternName: string, type?: string, intent?: string, file?: string): Promise<ToolResult>;
|
|
8
8
|
export declare function handleSecurityAudit(cwd: string): Promise<ToolResult>;
|
|
9
9
|
export {};
|
|
@@ -5,13 +5,59 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @since v2.17.0 — extracted from monolithic index.ts
|
|
7
7
|
*/
|
|
8
|
+
import path from "path";
|
|
9
|
+
import yaml from "yaml";
|
|
10
|
+
import fs from "fs-extra";
|
|
8
11
|
import { PatternMatcher, loadPatternIndex, getDefaultIndexPath, StalenessDetector, SecurityDetector, } from "@rigour-labs/core/pattern-index";
|
|
12
|
+
import { ConfigSchema } from "@rigour-labs/core";
|
|
9
13
|
import { notifyProgress } from '../utils/notifications.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Check if a file path is protected by safety.protected_paths in rigour.yml.
|
|
16
|
+
* Returns the matched pattern or null.
|
|
17
|
+
*/
|
|
18
|
+
async function checkFileGuard(cwd, filePath) {
|
|
19
|
+
const configPath = path.join(cwd, 'rigour.yml');
|
|
20
|
+
let protectedPaths = [];
|
|
21
|
+
try {
|
|
22
|
+
if (await fs.pathExists(configPath)) {
|
|
23
|
+
const raw = yaml.parse(await fs.readFile(configPath, 'utf-8'));
|
|
24
|
+
const config = ConfigSchema.parse(raw);
|
|
25
|
+
protectedPaths = config.gates.safety?.protected_paths ?? [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Default protected paths if no config
|
|
30
|
+
protectedPaths = ['.github/**', 'rigour.yml'];
|
|
31
|
+
}
|
|
32
|
+
if (protectedPaths.length === 0)
|
|
33
|
+
return null;
|
|
34
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
35
|
+
return protectedPaths.find(pattern => {
|
|
36
|
+
const clean = pattern.replace('/**', '').replace('/*', '');
|
|
37
|
+
if (normalized === clean)
|
|
38
|
+
return true;
|
|
39
|
+
if (clean.endsWith('/'))
|
|
40
|
+
return normalized.startsWith(clean);
|
|
41
|
+
return normalized.startsWith(clean + '/');
|
|
42
|
+
}) ?? null;
|
|
43
|
+
}
|
|
44
|
+
export async function handleCheckPattern(cwd, patternName, type, intent, file) {
|
|
13
45
|
let resultText = "";
|
|
46
|
+
// 0. File Guard — BLOCK writes to protected paths
|
|
47
|
+
if (file) {
|
|
48
|
+
const matched = await checkFileGuard(cwd, file);
|
|
49
|
+
if (matched) {
|
|
50
|
+
notifyProgress("error", `BLOCKED: Write to protected path ${file}`);
|
|
51
|
+
resultText = `🛑 BLOCKED: You CANNOT write to "${file}".\n`;
|
|
52
|
+
resultText += `This path matches protected pattern "${matched}" in rigour.yml.\n`;
|
|
53
|
+
resultText += `CI/CD pipelines, governance configs, and protected docs require human review.\n\n`;
|
|
54
|
+
resultText += `RECOMMENDED ACTION: STOP. Do not create or modify this file. Ask the human to make this change manually.`;
|
|
55
|
+
return { content: [{ type: "text", text: resultText }] };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
14
58
|
// 1. Check for Reinvention
|
|
59
|
+
const indexPath = getDefaultIndexPath(cwd);
|
|
60
|
+
const index = await loadPatternIndex(indexPath);
|
|
15
61
|
if (index) {
|
|
16
62
|
const matcher = new PatternMatcher(index);
|
|
17
63
|
const matchResult = await matcher.match({ name: patternName, type, intent });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/mcp",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.9",
|
|
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, Bayesian learning Brain, hallucinated import detection, multi-agent governance. Works with Claude, Cursor, VS Code, ChatGPT, Goose, Windsurf. Industry presets for HIPAA, SOC2, FedRAMP.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://rigour.run",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"execa": "^8.0.1",
|
|
63
63
|
"fs-extra": "^11.2.0",
|
|
64
64
|
"yaml": "^2.8.2",
|
|
65
|
-
"@rigour-labs/core": "5.2.
|
|
65
|
+
"@rigour-labs/core": "5.2.9"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/node": "^25.0.3",
|