@rigour-labs/mcp 3.0.0 → 3.0.2
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 +10 -2
- package/dist/tools/definitions.d.ts +49 -0
- package/dist/tools/definitions.js +28 -0
- package/dist/tools/hooks-handler.d.ts +18 -0
- package/dist/tools/hooks-handler.js +86 -0
- package/dist/utils/config.d.ts +7 -0
- package/package.json +16 -7
package/dist/index.js
CHANGED
|
@@ -23,8 +23,9 @@ import { handleCheckPattern, handleSecurityAudit } from './tools/pattern-handler
|
|
|
23
23
|
import { handleRun, handleRunSupervised } from './tools/execution-handlers.js';
|
|
24
24
|
import { handleAgentRegister, handleCheckpoint, handleHandoff, handleAgentDeregister, handleHandoffAccept } from './tools/agent-handlers.js';
|
|
25
25
|
import { handleReview } from './tools/review-handler.js';
|
|
26
|
+
import { handleHooksCheck, handleHooksInit } from './tools/hooks-handler.js';
|
|
26
27
|
// ─── Server Setup ─────────────────────────────────────────────────
|
|
27
|
-
const server = new Server({ name: "rigour-mcp", version: "
|
|
28
|
+
const server = new Server({ name: "rigour-mcp", version: "3.0.0" }, { capabilities: { tools: {} } });
|
|
28
29
|
// ─── Tool Listing ─────────────────────────────────────────────────
|
|
29
30
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
30
31
|
tools: TOOL_DEFINITIONS,
|
|
@@ -105,6 +106,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
105
106
|
case "rigour_handoff_accept":
|
|
106
107
|
result = await handleHandoffAccept(cwd, args.handoffId, args.agentId, requestId);
|
|
107
108
|
break;
|
|
109
|
+
// Real-time hooks (v3.0)
|
|
110
|
+
case "rigour_hooks_check":
|
|
111
|
+
result = await handleHooksCheck(cwd, args.files, args.timeout);
|
|
112
|
+
break;
|
|
113
|
+
case "rigour_hooks_init":
|
|
114
|
+
result = await handleHooksInit(cwd, args.tool, args.force, args.dryRun);
|
|
115
|
+
break;
|
|
108
116
|
// Code review
|
|
109
117
|
case "rigour_review":
|
|
110
118
|
result = await handleReview(runner, cwd, args.diff, args.files);
|
|
@@ -134,7 +142,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
134
142
|
async function main() {
|
|
135
143
|
const transport = new StdioServerTransport();
|
|
136
144
|
await server.connect(transport);
|
|
137
|
-
console.error("Rigour MCP server
|
|
145
|
+
console.error("Rigour MCP server v3.0.0 running on stdio");
|
|
138
146
|
}
|
|
139
147
|
main().catch((error) => {
|
|
140
148
|
console.error("Fatal error in Rigour MCP server:", error);
|
|
@@ -258,6 +258,55 @@ export declare const TOOL_DEFINITIONS: ({
|
|
|
258
258
|
};
|
|
259
259
|
required: string[];
|
|
260
260
|
};
|
|
261
|
+
} | {
|
|
262
|
+
name: string;
|
|
263
|
+
description: string;
|
|
264
|
+
inputSchema: {
|
|
265
|
+
type: string;
|
|
266
|
+
properties: {
|
|
267
|
+
files: {
|
|
268
|
+
type: string;
|
|
269
|
+
items: {
|
|
270
|
+
type: string;
|
|
271
|
+
};
|
|
272
|
+
description: string;
|
|
273
|
+
};
|
|
274
|
+
timeout: {
|
|
275
|
+
type: string;
|
|
276
|
+
description: string;
|
|
277
|
+
};
|
|
278
|
+
cwd: {
|
|
279
|
+
type: "string";
|
|
280
|
+
description: string;
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
required: string[];
|
|
284
|
+
};
|
|
285
|
+
} | {
|
|
286
|
+
name: string;
|
|
287
|
+
description: string;
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: string;
|
|
290
|
+
properties: {
|
|
291
|
+
tool: {
|
|
292
|
+
type: string;
|
|
293
|
+
description: string;
|
|
294
|
+
};
|
|
295
|
+
force: {
|
|
296
|
+
type: string;
|
|
297
|
+
description: string;
|
|
298
|
+
};
|
|
299
|
+
dryRun: {
|
|
300
|
+
type: string;
|
|
301
|
+
description: string;
|
|
302
|
+
};
|
|
303
|
+
cwd: {
|
|
304
|
+
type: "string";
|
|
305
|
+
description: string;
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
required: string[];
|
|
309
|
+
};
|
|
261
310
|
} | {
|
|
262
311
|
name: string;
|
|
263
312
|
description: string;
|
|
@@ -230,6 +230,34 @@ export const TOOL_DEFINITIONS = [
|
|
|
230
230
|
required: ["cwd", "handoffId", "agentId"],
|
|
231
231
|
},
|
|
232
232
|
},
|
|
233
|
+
// ─── Real-Time Hooks (v3.0) ────────────────────────────
|
|
234
|
+
{
|
|
235
|
+
name: "rigour_hooks_check",
|
|
236
|
+
description: "Run the fast hook checker on specific files. Same checks that run inside IDE hooks (Claude, Cursor, Cline, Windsurf). Catches: hardcoded secrets, hallucinated imports, command injection, file size. Completes in <100ms.",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: "object",
|
|
239
|
+
properties: {
|
|
240
|
+
...cwdParam(),
|
|
241
|
+
files: { type: "array", items: { type: "string" }, description: "List of file paths (relative to cwd) to check." },
|
|
242
|
+
timeout: { type: "number", description: "Optional timeout in milliseconds (default: 5000)." },
|
|
243
|
+
},
|
|
244
|
+
required: ["cwd", "files"],
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: "rigour_hooks_init",
|
|
249
|
+
description: "Generate hook configs for AI coding tools (Claude, Cursor, Cline, Windsurf). Installs real-time quality checks that run on every file write.",
|
|
250
|
+
inputSchema: {
|
|
251
|
+
type: "object",
|
|
252
|
+
properties: {
|
|
253
|
+
...cwdParam(),
|
|
254
|
+
tool: { type: "string", description: "Target tool: 'claude', 'cursor', 'cline', or 'windsurf'." },
|
|
255
|
+
force: { type: "boolean", description: "Overwrite existing hook files (default: false)." },
|
|
256
|
+
dryRun: { type: "boolean", description: "Preview changes without writing files (default: false)." },
|
|
257
|
+
},
|
|
258
|
+
required: ["cwd", "tool"],
|
|
259
|
+
},
|
|
260
|
+
},
|
|
233
261
|
// ─── Code Review ──────────────────────────────────────
|
|
234
262
|
{
|
|
235
263
|
name: "rigour_review",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type ToolResult = {
|
|
2
|
+
content: {
|
|
3
|
+
type: string;
|
|
4
|
+
text: string;
|
|
5
|
+
}[];
|
|
6
|
+
isError?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* rigour_hooks_check — Run the fast hook checker on specific files.
|
|
10
|
+
* This is the same check that runs inside IDE hooks (Claude, Cursor, Cline, Windsurf).
|
|
11
|
+
* Catches: hardcoded secrets, hallucinated imports, command injection, file size.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleHooksCheck(cwd: string, files: string[], timeout?: number): Promise<ToolResult>;
|
|
14
|
+
/**
|
|
15
|
+
* rigour_hooks_init — Generate hook configs for AI coding tools.
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleHooksInit(cwd: string, tool: string, force?: boolean, dryRun?: boolean): Promise<ToolResult>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hooks Tool Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handlers for: rigour_hooks_check, rigour_hooks_init
|
|
5
|
+
*
|
|
6
|
+
* @since v3.0.0 — real-time hooks for AI coding tools
|
|
7
|
+
*/
|
|
8
|
+
import { runHookChecker, generateHookFiles } from "@rigour-labs/core";
|
|
9
|
+
import fs from "fs-extra";
|
|
10
|
+
import path from "path";
|
|
11
|
+
/**
|
|
12
|
+
* rigour_hooks_check — Run the fast hook checker on specific files.
|
|
13
|
+
* This is the same check that runs inside IDE hooks (Claude, Cursor, Cline, Windsurf).
|
|
14
|
+
* Catches: hardcoded secrets, hallucinated imports, command injection, file size.
|
|
15
|
+
*/
|
|
16
|
+
export async function handleHooksCheck(cwd, files, timeout) {
|
|
17
|
+
const input = { cwd, files };
|
|
18
|
+
if (timeout)
|
|
19
|
+
input.timeout_ms = timeout;
|
|
20
|
+
const result = await runHookChecker(input);
|
|
21
|
+
if (result.status === 'pass') {
|
|
22
|
+
return {
|
|
23
|
+
content: [{
|
|
24
|
+
type: "text",
|
|
25
|
+
text: `✓ PASS — ${files.length} file(s) passed all hook checks.\nDuration: ${result.duration_ms}ms`,
|
|
26
|
+
}],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const failureLines = result.failures.map(f => ` [${f.severity.toUpperCase()}] [${f.gate}] ${f.file}:${f.line ?? '?'}\n → ${f.message}`).join('\n');
|
|
30
|
+
return {
|
|
31
|
+
content: [{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: `✘ FAIL — ${result.failures.length} issue(s) found in ${files.length} file(s).\nDuration: ${result.duration_ms}ms\n\n${failureLines}`,
|
|
34
|
+
}],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* rigour_hooks_init — Generate hook configs for AI coding tools.
|
|
39
|
+
*/
|
|
40
|
+
export async function handleHooksInit(cwd, tool, force = false, dryRun = false) {
|
|
41
|
+
try {
|
|
42
|
+
const hookTool = tool;
|
|
43
|
+
const checkerPath = 'npx @rigour-labs/cli hooks check';
|
|
44
|
+
const files = generateHookFiles(hookTool, checkerPath);
|
|
45
|
+
if (dryRun) {
|
|
46
|
+
const preview = files.map(f => `${f.path}:\n${f.content}`).join('\n\n');
|
|
47
|
+
return {
|
|
48
|
+
content: [{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: `[DRY RUN] Would generate ${files.length} hook file(s) for '${tool}':\n\n${preview}`,
|
|
51
|
+
}],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const written = [];
|
|
55
|
+
const skipped = [];
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
const fullPath = path.join(cwd, file.path);
|
|
58
|
+
if (!force && await fs.pathExists(fullPath)) {
|
|
59
|
+
skipped.push(file.path);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
await fs.ensureDir(path.dirname(fullPath));
|
|
63
|
+
await fs.writeFile(fullPath, file.content);
|
|
64
|
+
written.push(file.path);
|
|
65
|
+
}
|
|
66
|
+
const parts = [];
|
|
67
|
+
if (written.length > 0)
|
|
68
|
+
parts.push(`✓ Created: ${written.join(', ')}`);
|
|
69
|
+
if (skipped.length > 0)
|
|
70
|
+
parts.push(`⊘ Skipped (exists): ${skipped.join(', ')}. Use force=true to overwrite.`);
|
|
71
|
+
parts.push(`Tool: ${tool}`);
|
|
72
|
+
parts.push('Checks: file-size, security-patterns, hallucinated-imports, command-injection');
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: "text", text: parts.join('\n') }],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
content: [{
|
|
80
|
+
type: "text",
|
|
81
|
+
text: `Hook init failed: ${error.message}\n\nFallback: run 'npx @rigour-labs/cli hooks init --tool ${tool}' from the terminal.`,
|
|
82
|
+
}],
|
|
83
|
+
isError: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -126,6 +126,13 @@ export declare function loadConfig(cwd: string): Promise<{
|
|
|
126
126
|
check_unsafe_fetch: boolean;
|
|
127
127
|
};
|
|
128
128
|
};
|
|
129
|
+
hooks: {
|
|
130
|
+
enabled: boolean;
|
|
131
|
+
tools: ("claude" | "cursor" | "cline" | "windsurf")[];
|
|
132
|
+
fast_gates: string[];
|
|
133
|
+
timeout_ms: number;
|
|
134
|
+
block_on_failure: boolean;
|
|
135
|
+
};
|
|
129
136
|
output: {
|
|
130
137
|
report_path: string;
|
|
131
138
|
};
|
package/package.json
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/mcp",
|
|
3
|
-
"version": "3.0.
|
|
4
|
-
"description": "MCP server for AI code
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"description": "MCP server for AI code governance — OWASP LLM Top 10 (10/10), real-time hooks, 25+ security patterns, hallucinated import detection, multi-agent governance. Works with Claude, Cursor, Cline, Windsurf, Gemini. Industry presets for HIPAA, SOC2, FedRAMP.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://rigour.run",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"mcp",
|
|
9
9
|
"model-context-protocol",
|
|
10
|
-
"
|
|
11
|
-
"ai-code-
|
|
10
|
+
"owasp-llm-top-10",
|
|
11
|
+
"ai-code-governance",
|
|
12
|
+
"real-time-hooks",
|
|
13
|
+
"security-patterns",
|
|
14
|
+
"hallucinated-imports",
|
|
15
|
+
"industry-presets",
|
|
16
|
+
"hipaa",
|
|
17
|
+
"soc2",
|
|
18
|
+
"fedramp",
|
|
12
19
|
"claude",
|
|
13
20
|
"cursor",
|
|
14
21
|
"cline",
|
|
15
|
-
"
|
|
22
|
+
"windsurf",
|
|
23
|
+
"multi-agent-governance",
|
|
24
|
+
"quality-gates",
|
|
16
25
|
"static-analysis",
|
|
17
|
-
"
|
|
26
|
+
"code-review"
|
|
18
27
|
],
|
|
19
28
|
"type": "module",
|
|
20
29
|
"mcpName": "io.github.rigour-labs/rigour",
|
|
@@ -38,7 +47,7 @@
|
|
|
38
47
|
"execa": "^8.0.1",
|
|
39
48
|
"fs-extra": "^11.2.0",
|
|
40
49
|
"yaml": "^2.8.2",
|
|
41
|
-
"@rigour-labs/core": "3.0.
|
|
50
|
+
"@rigour-labs/core": "3.0.2"
|
|
42
51
|
},
|
|
43
52
|
"devDependencies": {
|
|
44
53
|
"@types/node": "^25.0.3",
|