@rigour-labs/mcp 6.4.4 → 6.5.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.
@@ -1,6 +1,6 @@
1
1
  export declare const TOOL_GROUPS: {
2
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"];
3
+ readonly core: readonly ["rigour_recall", "rigour_index", "rigour_context_scope", "rigour_check_pattern", "rigour_check", "rigour_review", "rigour_review_ack", "rigour_get_fix_packet", "rigour_remember"];
4
4
  /** Multi-agent registration, checkpoints, handoffs, hooks and supervised runs. */
5
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
6
  /** Occasional context and security tools. */
@@ -623,6 +623,47 @@ export declare function getAdvertisedToolDefinitions(spec?: string): ({
623
623
  };
624
624
  description: string;
625
625
  };
626
+ mode: {
627
+ type: string;
628
+ enum: string[];
629
+ description: string;
630
+ };
631
+ cwd: {
632
+ type: "string";
633
+ description: string;
634
+ };
635
+ };
636
+ required: string[];
637
+ };
638
+ annotations: {
639
+ title: string;
640
+ readOnlyHint: boolean;
641
+ destructiveHint: boolean;
642
+ idempotentHint: boolean;
643
+ openWorldHint: boolean;
644
+ };
645
+ } | {
646
+ name: string;
647
+ description: string;
648
+ inputSchema: {
649
+ type: string;
650
+ properties: {
651
+ file: {
652
+ type: string;
653
+ description: string;
654
+ };
655
+ function: {
656
+ type: string;
657
+ description: string;
658
+ };
659
+ verdict: {
660
+ type: string;
661
+ enum: string[];
662
+ };
663
+ note: {
664
+ type: string;
665
+ description: string;
666
+ };
626
667
  cwd: {
627
668
  type: "string";
628
669
  description: string;
@@ -17,6 +17,7 @@ export const TOOL_GROUPS = {
17
17
  'rigour_check_pattern',
18
18
  'rigour_check',
19
19
  'rigour_review',
20
+ 'rigour_review_ack',
20
21
  'rigour_get_fix_packet',
21
22
  'rigour_remember',
22
23
  ],
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
11
11
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
12
12
  import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
13
13
  import { randomUUID } from "crypto";
14
- import { GateRunner } from "@rigour-labs/core";
14
+ import { GateRunner, countUsage, flushDailyUsage } from "@rigour-labs/core";
15
15
  // Utils
16
16
  import { loadConfig, loadMcpSettings, logStudioEvent } from './utils/config.js';
17
17
  import { bindServer } from './utils/notifications.js';
@@ -27,7 +27,7 @@ import { handleRemember, handleRecall, handleForget } from './tools/memory-handl
27
27
  import { handleCheckPattern, handleSecurityAudit } from './tools/pattern-handlers.js';
28
28
  import { handleRun, handleRunSupervised } from './tools/execution-handlers.js';
29
29
  import { handleAgentRegister, handleCheckpoint, handleHandoff, handleAgentDeregister, handleHandoffAccept } from './tools/agent-handlers.js';
30
- import { handleReview } from './tools/review-handler.js';
30
+ import { handleReview, handleReviewAck } from './tools/review-handler.js';
31
31
  import { handleHooksCheck, handleHooksInit } from './tools/hooks-handler.js';
32
32
  import { handleCheckDeep, handleDeepStats } from './tools/deep-handlers.js';
33
33
  import { handleMcpGetSettings, handleMcpSetSettings } from './tools/mcp-settings-handler.js';
@@ -216,6 +216,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
216
216
  case "rigour_review":
217
217
  result = await handleReview(config, cwd, args);
218
218
  break;
219
+ case "rigour_review_ack":
220
+ result = handleReviewAck(cwd, args);
221
+ break;
219
222
  // Context Telemetry & Cost Tools
220
223
  case "rigour_context_stats":
221
224
  result = await handleContextStats(cwd, args.taskId);
@@ -334,9 +337,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
334
337
  catch {
335
338
  // Client doesn't support resource notifications — fine
336
339
  }
340
+ countUsage(`mcp:${name}`);
337
341
  return result;
338
342
  }
339
343
  catch (error) {
344
+ countUsage(`mcp_error:${name}`);
340
345
  const errorResponse = {
341
346
  content: [{ type: "text", text: `RIGOUR ERROR: ${error.message}` }],
342
347
  isError: true,
@@ -427,7 +432,7 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
427
432
  role: "user",
428
433
  content: {
429
434
  type: "text",
430
- text: `Run a pre-commit quality check on ${cwd}. Execute \`rigour_check\` (default deep mode "${deepMode}") and \`rigour_hooks_check\` on all staged files. If any critical or high severity violations exist, list them and block the commit. For medium/low violations, warn but allow. Provide a one-line summary: PASS (safe to commit) or FAIL (must fix first).`,
435
+ text: `Run a pre-commit review on ${cwd}. Call \`rigour_review\` with mode "agent". Fix every critical or high failure. Then review each review_task item yourself: read the function, its callers and what it calls, answer its questions against the code, fix any real defect, and call \`rigour_review_ack\` with what you checked. Call \`rigour_review\` again to confirm. Provide a one-line summary: PASS (safe to commit) or FAIL (must fix first).`,
431
436
  },
432
437
  },
433
438
  ],
@@ -476,6 +481,7 @@ async function main() {
476
481
  }
477
482
  const transport = new StdioServerTransport();
478
483
  await server.connect(transport);
484
+ void flushDailyUsage(); // a day's agent activity, if a day has passed; never awaited by the agent
479
485
  console.error("Rigour MCP server v4.0.0 running on stdio");
480
486
  }
481
487
  main().catch((error) => {
@@ -626,6 +626,47 @@ export declare const TOOL_DEFINITIONS: ({
626
626
  };
627
627
  description: string;
628
628
  };
629
+ mode: {
630
+ type: string;
631
+ enum: string[];
632
+ description: string;
633
+ };
634
+ cwd: {
635
+ type: "string";
636
+ description: string;
637
+ };
638
+ };
639
+ required: string[];
640
+ };
641
+ annotations: {
642
+ title: string;
643
+ readOnlyHint: boolean;
644
+ destructiveHint: boolean;
645
+ idempotentHint: boolean;
646
+ openWorldHint: boolean;
647
+ };
648
+ } | {
649
+ name: string;
650
+ description: string;
651
+ inputSchema: {
652
+ type: string;
653
+ properties: {
654
+ file: {
655
+ type: string;
656
+ description: string;
657
+ };
658
+ function: {
659
+ type: string;
660
+ description: string;
661
+ };
662
+ verdict: {
663
+ type: string;
664
+ enum: string[];
665
+ };
666
+ note: {
667
+ type: string;
668
+ description: string;
669
+ };
629
670
  cwd: {
630
671
  type: "string";
631
672
  description: string;
@@ -519,6 +519,7 @@ export const TOOL_DEFINITIONS = [
519
519
  base: { type: "string", description: "Review this branch against a base ref instead of uncommitted work, e.g. 'main'." },
520
520
  diff: { type: "string", description: "A unified diff to review instead of reading git. Rarely needed." },
521
521
  files: { type: "array", items: { type: "string" }, description: "Review exactly these files instead of the ones the change touches." },
522
+ mode: { type: "string", enum: ["gates", "agent"], description: "\"agent\": also return review_task, the risky changed functions for you to review yourself, with what to check in each. No model is called by Rigour." },
522
523
  },
523
524
  required: ["cwd"],
524
525
  },
@@ -530,6 +531,28 @@ export const TOOL_DEFINITIONS = [
530
531
  openWorldHint: false,
531
532
  },
532
533
  },
534
+ {
535
+ name: "rigour_review_ack",
536
+ description: "Record that you reviewed a function from rigour_review's review_task: verdict \"fixed\" (you fixed a defect) or \"no_issue\", with a note saying what you checked. Covers the function's current code only; editing it later puts it back in the task.",
537
+ inputSchema: {
538
+ type: "object",
539
+ properties: {
540
+ ...cwdParam(),
541
+ file: { type: "string", description: "Repository-relative path, as in review_task." },
542
+ function: { type: "string", description: "Function name, as in review_task." },
543
+ verdict: { type: "string", enum: ["fixed", "no_issue"] },
544
+ note: { type: "string", description: "What you checked, e.g. 'callers pass a non-empty cursor; upsert conflict key matches the unique index'." },
545
+ },
546
+ required: ["cwd", "file", "function", "verdict", "note"],
547
+ },
548
+ annotations: {
549
+ title: "Acknowledge Review",
550
+ readOnlyHint: false,
551
+ destructiveHint: false,
552
+ idempotentHint: true,
553
+ openWorldHint: false,
554
+ },
555
+ },
533
556
  // ─── Context Telemetry & Cost Efficiency ───────────────
534
557
  {
535
558
  name: "rigour_context_stats",
@@ -42,7 +42,7 @@ export const PROMPT_DEFINITIONS = [
42
42
  },
43
43
  {
44
44
  name: "rigour-pre-commit",
45
- description: "Pre-commit quality gate check. Runs fast hooks on staged files and full gate check. Returns PASS/FAIL verdict for commit safety.",
45
+ description: "Pre-commit review: Rigour's gates plus your own review of the risky changed functions it picks, acknowledged one by one. Returns PASS/FAIL.",
46
46
  arguments: [
47
47
  {
48
48
  name: "cwd",
@@ -17,6 +17,16 @@ export interface ReviewArgs {
17
17
  diff?: string;
18
18
  base?: string;
19
19
  files?: string[];
20
+ /** "agent": also return the risky changed functions for the calling agent to review itself. */
21
+ mode?: 'gates' | 'agent';
22
+ }
23
+ export interface ReviewAckArgs {
24
+ file: string;
25
+ function: string;
26
+ verdict: string;
27
+ note: string;
20
28
  }
21
29
  export declare function handleReview(config: Config, cwd: string, args: ReviewArgs): Promise<ToolResult>;
30
+ /** rigour_review_ack: record that a review-task function was checked (verdict and what was checked). */
31
+ export declare function handleReviewAck(cwd: string, args: ReviewAckArgs): ToolResult;
22
32
  export {};
@@ -5,16 +5,14 @@
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 { recordReviewOutcome, reviewChange, toReviewFinding } from "@rigour-labs/core";
8
+ import { acknowledgeReview, buildReviewTask, diffFromGit, recordReviewOutcome, reviewChange, toReviewFinding } from "@rigour-labs/core";
9
9
  import { notifyProgress } from '../utils/notifications.js';
10
10
  export async function handleReview(config, cwd, args) {
11
11
  notifyProgress("info", args.diff ? "Reviewing the provided diff..." : `Reviewing ${args.base ? `this branch against ${args.base}` : "uncommitted changes"}...`);
12
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
- });
13
+ const diff = args.diff ?? diffFromGit(cwd, args.base ? { mode: 'base', base: args.base } : { mode: 'working' });
14
+ const result = await reviewChange({ cwd, config, diff, files: args.files });
15
+ const task = args.mode === 'agent' ? buildReviewTask(cwd, diff, config.gates.deep?.router, config.gates.deep?.review_lessons, config.gates.deep?.repo_rules) : undefined;
18
16
  recordReviewOutcome(cwd, result.findings, Object.keys(result.changedLines));
19
17
  const stats = result.report?.stats;
20
18
  return text({
@@ -25,17 +23,32 @@ export async function handleReview(config, cwd, args) {
25
23
  changed_files: Object.keys(result.changedLines).length,
26
24
  failures: result.findings.map(toReviewFinding),
27
25
  file_findings: result.fileFindings.map(toReviewFinding),
26
+ context_findings: result.contextFindings.map(toReviewFinding),
27
+ advisory_count: result.advisory.length,
28
28
  excluded_outside_changed_lines: result.excludedOutsideChangedLines,
29
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.",
30
+ ...(task ? { review_task: { items: task.items, already_reviewed: task.alreadyReviewed, team_lessons: task.lessons, repo_rules: task.rules, instructions: task.instructions } } : {}),
31
+ next_step: nextStep(result.findings.length, task?.items.length ?? 0),
33
32
  });
34
33
  }
35
34
  catch (error) {
36
35
  return { ...text({ error: error instanceof Error ? error.message : String(error) }), isError: true };
37
36
  }
38
37
  }
38
+ /** rigour_review_ack: record that a review-task function was checked (verdict and what was checked). */
39
+ export function handleReviewAck(cwd, args) {
40
+ const result = acknowledgeReview(cwd, { ...args, reviewer: 'agent' });
41
+ if (!result.ok)
42
+ return { ...text({ error: result.error }), isError: true };
43
+ return text({ recorded: { file: result.entry.file, function: result.entry.function, verdict: result.entry.verdict } });
44
+ }
45
+ function nextStep(findings, unreviewed) {
46
+ if (findings)
47
+ return "Fix each failure at its file:line (see suggestion), then call rigour_review again.";
48
+ if (unreviewed)
49
+ return "Review each review_task item (read its callers and callees, answer its questions), fix real defects, then call rigour_review_ack for it.";
50
+ return "No findings on changed lines.";
51
+ }
39
52
  function text(value) {
40
53
  return { content: [{ type: "text", text: JSON.stringify(value) }] };
41
54
  }
@@ -37,6 +37,15 @@ export declare function loadConfig(cwd: string): Promise<{
37
37
  model_path?: string | undefined;
38
38
  max_tokens?: number | undefined;
39
39
  timeout_ms?: number | undefined;
40
+ budget_ms?: number | undefined;
41
+ agentic?: boolean | undefined;
42
+ repo_rules?: boolean | undefined;
43
+ review_lessons?: "verified" | "all" | "off" | undefined;
44
+ router?: {
45
+ enabled?: boolean | undefined;
46
+ min_score?: number | undefined;
47
+ max_functions?: number | undefined;
48
+ } | undefined;
40
49
  };
41
50
  max_file_lines: number;
42
51
  forbid_todos: boolean;
@@ -253,11 +262,15 @@ export declare function loadConfig(cwd: string): Promise<{
253
262
  timeout_ms: number;
254
263
  fast_gates: string[];
255
264
  block_on_failure: boolean;
265
+ require_review_ack: boolean;
256
266
  dlp: boolean;
257
267
  };
258
268
  output: {
259
269
  report_path: string;
260
270
  };
271
+ review: {
272
+ include_heuristics: boolean;
273
+ };
261
274
  planned: string[];
262
275
  preset?: string | undefined;
263
276
  paradigm?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/mcp",
3
- "version": "6.4.4",
3
+ "version": "6.5.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, 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
  "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.4.4"
68
+ "@rigour-labs/core": "6.5.1"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.0.3",