@rigour-labs/mcp 6.3.0 → 6.4.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/advertised-tools.d.ts +15 -10
- package/dist/advertised-tools.js +53 -40
- package/dist/index.js +1 -1
- package/dist/tools/definitions.d.ts +1 -5
- package/dist/tools/definitions.js +6 -7
- package/dist/tools/review-handler.d.ts +12 -6
- package/dist/tools/review-handler.js +35 -45
- package/dist/utils/config.d.ts +5 -0
- package/dist/utils/config.js +14 -9
- package/package.json +2 -2
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export declare const TOOL_GROUPS: {
|
|
2
|
+
/** Load memory, scope context, avoid reinvention, gate and review the change, learn. */
|
|
3
|
+
readonly core: readonly ["rigour_recall", "rigour_index", "rigour_context_scope", "rigour_check_pattern", "rigour_check", "rigour_review", "rigour_get_fix_packet", "rigour_remember"];
|
|
4
|
+
/** Multi-agent registration, checkpoints, handoffs, hooks and supervised runs. */
|
|
5
|
+
readonly governance: readonly ["rigour_agent_register", "rigour_agent_deregister", "rigour_checkpoint", "rigour_handoff", "rigour_handoff_accept", "rigour_hooks_check", "rigour_hooks_init", "rigour_run", "rigour_run_supervised"];
|
|
6
|
+
/** Occasional context and security tools. */
|
|
7
|
+
readonly context: readonly ["rigour_explain", "rigour_forget", "rigour_context_explain", "rigour_security_audit"];
|
|
8
|
+
/** Cost and cache telemetry, mostly for dashboards. */
|
|
9
|
+
readonly telemetry: readonly ["rigour_context_stats", "rigour_task_cost", "rigour_cache_stats"];
|
|
10
|
+
};
|
|
11
|
+
export type ToolGroup = keyof typeof TOOL_GROUPS;
|
|
4
12
|
export declare const GOVERNANCE_TOOLS: readonly ["rigour_agent_register", "rigour_agent_deregister", "rigour_checkpoint", "rigour_handoff", "rigour_handoff_accept", "rigour_hooks_check", "rigour_hooks_init", "rigour_run", "rigour_run_supervised"];
|
|
5
|
-
|
|
6
|
-
export declare function
|
|
13
|
+
/** Tool names for a RIGOUR_MCP_TOOLS value; core is always included, unknown groups are ignored. */
|
|
14
|
+
export declare function advertisedToolNames(spec?: string | undefined): Set<string>;
|
|
15
|
+
export declare function getAdvertisedToolDefinitions(spec?: string): ({
|
|
7
16
|
name: string;
|
|
8
17
|
description: string;
|
|
9
18
|
inputSchema: {
|
|
@@ -599,11 +608,7 @@ export declare function getAdvertisedToolDefinitions(): ({
|
|
|
599
608
|
inputSchema: {
|
|
600
609
|
type: string;
|
|
601
610
|
properties: {
|
|
602
|
-
|
|
603
|
-
type: string;
|
|
604
|
-
description: string;
|
|
605
|
-
};
|
|
606
|
-
branch: {
|
|
611
|
+
base: {
|
|
607
612
|
type: string;
|
|
608
613
|
description: string;
|
|
609
614
|
};
|
package/dist/advertised-tools.js
CHANGED
|
@@ -1,46 +1,59 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP tools advertised to clients via ListTools.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Every advertised tool costs every agent session its definition in context
|
|
5
|
+
* and one more choice to get wrong, so the default is the core loop a single
|
|
6
|
+
* agent needs. Other groups are opt-in through RIGOUR_MCP_TOOLS in the MCP
|
|
7
|
+
* client's config, e.g. "governance,telemetry" or "full". Tools outside the
|
|
8
|
+
* advertised set stay callable; they are just not listed.
|
|
8
9
|
*/
|
|
9
10
|
import { TOOL_DEFINITIONS } from './tools/definitions.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
11
|
+
export const TOOL_GROUPS = {
|
|
12
|
+
/** Load memory, scope context, avoid reinvention, gate and review the change, learn. */
|
|
13
|
+
core: [
|
|
14
|
+
'rigour_recall',
|
|
15
|
+
'rigour_index',
|
|
16
|
+
'rigour_context_scope',
|
|
17
|
+
'rigour_check_pattern',
|
|
18
|
+
'rigour_check',
|
|
19
|
+
'rigour_review',
|
|
20
|
+
'rigour_get_fix_packet',
|
|
21
|
+
'rigour_remember',
|
|
22
|
+
],
|
|
23
|
+
/** Multi-agent registration, checkpoints, handoffs, hooks and supervised runs. */
|
|
24
|
+
governance: [
|
|
25
|
+
'rigour_agent_register',
|
|
26
|
+
'rigour_agent_deregister',
|
|
27
|
+
'rigour_checkpoint',
|
|
28
|
+
'rigour_handoff',
|
|
29
|
+
'rigour_handoff_accept',
|
|
30
|
+
'rigour_hooks_check',
|
|
31
|
+
'rigour_hooks_init',
|
|
32
|
+
'rigour_run',
|
|
33
|
+
'rigour_run_supervised',
|
|
34
|
+
],
|
|
35
|
+
/** Occasional context and security tools. */
|
|
36
|
+
context: [
|
|
37
|
+
'rigour_explain',
|
|
38
|
+
'rigour_forget',
|
|
39
|
+
'rigour_context_explain',
|
|
40
|
+
'rigour_security_audit',
|
|
41
|
+
],
|
|
42
|
+
/** Cost and cache telemetry, mostly for dashboards. */
|
|
43
|
+
telemetry: [
|
|
44
|
+
'rigour_context_stats',
|
|
45
|
+
'rigour_task_cost',
|
|
46
|
+
'rigour_cache_stats',
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
export const GOVERNANCE_TOOLS = TOOL_GROUPS.governance;
|
|
50
|
+
/** Tool names for a RIGOUR_MCP_TOOLS value; core is always included, unknown groups are ignored. */
|
|
51
|
+
export function advertisedToolNames(spec = process.env.RIGOUR_MCP_TOOLS) {
|
|
52
|
+
const requested = (spec ?? '').split(',').map(s => s.trim().toLowerCase()).filter(Boolean);
|
|
53
|
+
const groups = requested.includes('full') ? Object.keys(TOOL_GROUPS) : ['core', ...requested];
|
|
54
|
+
return new Set(groups.filter((g) => g in TOOL_GROUPS).flatMap(g => [...TOOL_GROUPS[g]]));
|
|
55
|
+
}
|
|
56
|
+
export function getAdvertisedToolDefinitions(spec) {
|
|
57
|
+
const names = advertisedToolNames(spec);
|
|
58
|
+
return TOOL_DEFINITIONS.filter(t => names.has(t.name));
|
|
46
59
|
}
|
package/dist/index.js
CHANGED
|
@@ -214,7 +214,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
214
214
|
break;
|
|
215
215
|
// Code review
|
|
216
216
|
case "rigour_review":
|
|
217
|
-
result = await handleReview(
|
|
217
|
+
result = await handleReview(config, cwd, args);
|
|
218
218
|
break;
|
|
219
219
|
// Context Telemetry & Cost Tools
|
|
220
220
|
case "rigour_context_stats":
|
|
@@ -511,20 +511,19 @@ export const TOOL_DEFINITIONS = [
|
|
|
511
511
|
// ─── Code Review ──────────────────────────────────────
|
|
512
512
|
{
|
|
513
513
|
name: "rigour_review",
|
|
514
|
-
description: "
|
|
514
|
+
description: "Review the change you just made before calling it done: runs Rigour's gates and keeps only findings on changed lines, each with file, line and a suggested fix. With no diff it reads your uncommitted work from git (new files included); pass base to review the whole branch (e.g. 'main'). Same verdict as `rigour review` in CI.",
|
|
515
515
|
inputSchema: {
|
|
516
516
|
type: "object",
|
|
517
517
|
properties: {
|
|
518
518
|
...cwdParam(),
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
files: { type: "array", items: { type: "string" }, description: "List of filenames that were changed." },
|
|
519
|
+
base: { type: "string", description: "Review this branch against a base ref instead of uncommitted work, e.g. 'main'." },
|
|
520
|
+
diff: { type: "string", description: "A unified diff to review instead of reading git. Rarely needed." },
|
|
521
|
+
files: { type: "array", items: { type: "string" }, description: "Review exactly these files instead of the ones the change touches." },
|
|
523
522
|
},
|
|
524
|
-
required: ["cwd"
|
|
523
|
+
required: ["cwd"],
|
|
525
524
|
},
|
|
526
525
|
annotations: {
|
|
527
|
-
title: "
|
|
526
|
+
title: "Review Change",
|
|
528
527
|
readOnlyHint: true,
|
|
529
528
|
destructiveHint: false,
|
|
530
529
|
idempotentHint: true,
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* rigour_review: the same review as `rigour review` (core reviewChange), so an
|
|
3
|
+
* agent and CI get the same verdict for the same change.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @since v2.17.0 — extracted from monolithic index.ts
|
|
5
|
+
* With no diff, the change is taken from git: uncommitted work (what the
|
|
6
|
+
* agent just wrote, new files included), or the branch against `base`.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { type Config } from "@rigour-labs/core";
|
|
9
9
|
type ToolResult = {
|
|
10
10
|
content: {
|
|
11
11
|
type: string;
|
|
12
12
|
text: string;
|
|
13
13
|
}[];
|
|
14
|
+
isError?: boolean;
|
|
14
15
|
};
|
|
15
|
-
export
|
|
16
|
+
export interface ReviewArgs {
|
|
17
|
+
diff?: string;
|
|
18
|
+
base?: string;
|
|
19
|
+
files?: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function handleReview(config: Config, cwd: string, args: ReviewArgs): Promise<ToolResult>;
|
|
16
22
|
export {};
|
|
@@ -1,51 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* rigour_review: the same review as `rigour review` (core reviewChange), so an
|
|
3
|
+
* agent and CI get the same verdict for the same change.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @since v2.17.0 — extracted from monolithic index.ts
|
|
5
|
+
* With no diff, the change is taken from git: uncommitted work (what the
|
|
6
|
+
* agent just wrote, new files included), or the branch against `base`.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { recordReviewOutcome, reviewChange, toReviewFinding } from "@rigour-labs/core";
|
|
9
9
|
import { notifyProgress } from '../utils/notifications.js';
|
|
10
|
-
export async function handleReview(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
export async function handleReview(config, cwd, args) {
|
|
11
|
+
notifyProgress("info", args.diff ? "Reviewing the provided diff..." : `Reviewing ${args.base ? `this branch against ${args.base}` : "uncommitted changes"}...`);
|
|
12
|
+
try {
|
|
13
|
+
const result = await reviewChange({
|
|
14
|
+
cwd, config, diff: args.diff,
|
|
15
|
+
source: args.base ? { mode: 'base', base: args.base } : { mode: 'working' },
|
|
16
|
+
files: args.files,
|
|
17
|
+
});
|
|
18
|
+
recordReviewOutcome(cwd, result.findings, Object.keys(result.changedLines));
|
|
19
|
+
const stats = result.report?.stats;
|
|
20
|
+
return text({
|
|
21
|
+
status: result.status,
|
|
22
|
+
score: stats?.score ?? 100,
|
|
23
|
+
ai_health_score: stats?.ai_health_score,
|
|
24
|
+
structural_score: stats?.structural_score,
|
|
25
|
+
changed_files: Object.keys(result.changedLines).length,
|
|
26
|
+
failures: result.findings.map(toReviewFinding),
|
|
27
|
+
file_findings: result.fileFindings.map(toReviewFinding),
|
|
28
|
+
excluded_outside_changed_lines: result.excludedOutsideChangedLines,
|
|
29
|
+
unlocated_failures: result.unlocated,
|
|
30
|
+
next_step: result.findings.length
|
|
31
|
+
? "Fix each failure at its file:line (see suggestion), then call rigour_review again."
|
|
32
|
+
: "No findings on changed lines.",
|
|
28
33
|
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
ai_health_score: report.stats.ai_health_score,
|
|
37
|
-
structural_score: report.stats.structural_score,
|
|
38
|
-
failures: filteredFailures.map(f => ({
|
|
39
|
-
id: f.id,
|
|
40
|
-
gate: f.title,
|
|
41
|
-
severity: f.severity || 'medium',
|
|
42
|
-
provenance: f.provenance || 'traditional',
|
|
43
|
-
message: f.details,
|
|
44
|
-
file: f.files?.[0] || "",
|
|
45
|
-
line: f.line || 1,
|
|
46
|
-
suggestion: f.hint,
|
|
47
|
-
})),
|
|
48
|
-
}),
|
|
49
|
-
}],
|
|
50
|
-
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return { ...text({ error: error instanceof Error ? error.message : String(error) }), isError: true };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function text(value) {
|
|
40
|
+
return { content: [{ type: "text", text: JSON.stringify(value) }] };
|
|
51
41
|
}
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The repository's rigour.yml, or Rigour's defaults when it has none. A tool
|
|
3
|
+
* call never writes into the user's repository to create one (run `rigour init`
|
|
4
|
+
* for that), so the first call in a new repository behaves like `rigour review`.
|
|
5
|
+
*/
|
|
1
6
|
export declare function loadConfig(cwd: string): Promise<{
|
|
2
7
|
ignore: string[];
|
|
3
8
|
version: number;
|
package/dist/utils/config.js
CHANGED
|
@@ -12,22 +12,27 @@ import yaml from "yaml";
|
|
|
12
12
|
import { randomUUID } from "crypto";
|
|
13
13
|
import { ConfigSchema } from "@rigour-labs/core";
|
|
14
14
|
// ─── Config Loading ───────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* The repository's rigour.yml, or Rigour's defaults when it has none. A tool
|
|
17
|
+
* call never writes into the user's repository to create one (run `rigour init`
|
|
18
|
+
* for that), so the first call in a new repository behaves like `rigour review`.
|
|
19
|
+
*/
|
|
15
20
|
export async function loadConfig(cwd) {
|
|
16
21
|
const configPath = path.join(cwd, "rigour.yml");
|
|
17
22
|
if (!(await fs.pathExists(configPath))) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
await execa("npx", ["rigour", "init"], { cwd, shell: true });
|
|
22
|
-
console.error(`[RIGOUR] Auto-initialization complete.`);
|
|
23
|
-
}
|
|
24
|
-
catch (initError) {
|
|
25
|
-
throw new Error(`Rigour auto-initialization failed: ${initError.message}. Please run 'npx rigour init' manually.`);
|
|
26
|
-
}
|
|
23
|
+
noteMissingConfig(cwd);
|
|
24
|
+
return ConfigSchema.parse({ version: 1 });
|
|
27
25
|
}
|
|
28
26
|
const configContent = await fs.readFile(configPath, "utf-8");
|
|
29
27
|
return ConfigSchema.parse(yaml.parse(configContent));
|
|
30
28
|
}
|
|
29
|
+
const notedMissingConfig = new Set();
|
|
30
|
+
function noteMissingConfig(cwd) {
|
|
31
|
+
if (notedMissingConfig.has(cwd))
|
|
32
|
+
return;
|
|
33
|
+
notedMissingConfig.add(cwd);
|
|
34
|
+
console.error(`[RIGOUR] No rigour.yml in ${cwd}; using defaults. Run \`npx rigour init\` to configure gates and hooks.`);
|
|
35
|
+
}
|
|
31
36
|
export async function getMemoryPath(cwd) {
|
|
32
37
|
const rigourDir = path.join(cwd, ".rigour");
|
|
33
38
|
await fs.ensureDir(rigourDir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/mcp",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
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.4.0",
|
|
64
64
|
"yaml": "^2.8.2",
|
|
65
|
-
"@rigour-labs/core": "6.
|
|
65
|
+
"@rigour-labs/core": "6.4.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/node": "^25.0.3",
|