@rigour-labs/mcp 5.3.3 → 5.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.
@@ -0,0 +1,722 @@
1
+ /** Context, quality, and cost telemetry tools every agent should see first. */
2
+ export declare const ESSENTIAL_CONTEXT_TOOLS: readonly ["rigour_recall", "rigour_index", "rigour_context_scope", "rigour_check_pattern", "rigour_check", "rigour_remember", "rigour_explain", "rigour_get_fix_packet", "rigour_review", "rigour_security_audit", "rigour_forget", "rigour_context_stats", "rigour_task_cost", "rigour_cache_stats", "rigour_context_explain"];
3
+ /** Multi-agent governance, hooks, and execution tools with dispatch handlers. */
4
+ 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
+ export declare const ADVERTISED_TOOLS: Set<string>;
6
+ export declare function getAdvertisedToolDefinitions(): ({
7
+ name: string;
8
+ description: string;
9
+ inputSchema: {
10
+ type: string;
11
+ properties: {
12
+ files: {
13
+ type: string;
14
+ items: {
15
+ type: string;
16
+ };
17
+ description: string;
18
+ };
19
+ deep: {
20
+ type: string;
21
+ enum: string[];
22
+ description: string;
23
+ };
24
+ pro: {
25
+ type: string;
26
+ description: string;
27
+ };
28
+ apiKey: {
29
+ type: string;
30
+ description: string;
31
+ };
32
+ provider: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ apiBaseUrl: {
37
+ type: string;
38
+ description: string;
39
+ };
40
+ modelName: {
41
+ type: string;
42
+ description: string;
43
+ };
44
+ cwd: {
45
+ type: "string";
46
+ description: string;
47
+ };
48
+ };
49
+ required: string[];
50
+ };
51
+ annotations: {
52
+ title: string;
53
+ readOnlyHint: boolean;
54
+ destructiveHint: boolean;
55
+ idempotentHint: boolean;
56
+ openWorldHint: boolean;
57
+ };
58
+ } | {
59
+ name: string;
60
+ description: string;
61
+ inputSchema: {
62
+ type: string;
63
+ properties: {
64
+ cwd: {
65
+ type: "string";
66
+ description: string;
67
+ };
68
+ };
69
+ required: string[];
70
+ };
71
+ annotations: {
72
+ title: string;
73
+ readOnlyHint: boolean;
74
+ destructiveHint: boolean;
75
+ idempotentHint: boolean;
76
+ openWorldHint: boolean;
77
+ };
78
+ } | {
79
+ name: string;
80
+ description: string;
81
+ inputSchema: {
82
+ type: string;
83
+ properties: {
84
+ deep_default_mode: {
85
+ type: string;
86
+ enum: string[];
87
+ description: string;
88
+ };
89
+ cwd: {
90
+ type: "string";
91
+ description: string;
92
+ };
93
+ };
94
+ required: string[];
95
+ };
96
+ annotations: {
97
+ title: string;
98
+ readOnlyHint: boolean;
99
+ destructiveHint: boolean;
100
+ idempotentHint: boolean;
101
+ openWorldHint: boolean;
102
+ };
103
+ } | {
104
+ name: string;
105
+ description: string;
106
+ inputSchema: {
107
+ type: string;
108
+ properties: {
109
+ key: {
110
+ type: string;
111
+ description: string;
112
+ };
113
+ value: {
114
+ type: string;
115
+ description: string;
116
+ };
117
+ cwd: {
118
+ type: "string";
119
+ description: string;
120
+ };
121
+ };
122
+ required: string[];
123
+ };
124
+ annotations: {
125
+ title: string;
126
+ readOnlyHint: boolean;
127
+ destructiveHint: boolean;
128
+ idempotentHint: boolean;
129
+ openWorldHint: boolean;
130
+ };
131
+ } | {
132
+ name: string;
133
+ description: string;
134
+ inputSchema: {
135
+ type: string;
136
+ properties: {
137
+ key: {
138
+ type: string;
139
+ description: string;
140
+ };
141
+ cwd: {
142
+ type: "string";
143
+ description: string;
144
+ };
145
+ };
146
+ required: string[];
147
+ };
148
+ annotations: {
149
+ title: string;
150
+ readOnlyHint: boolean;
151
+ destructiveHint: boolean;
152
+ idempotentHint: boolean;
153
+ openWorldHint: boolean;
154
+ };
155
+ } | {
156
+ name: string;
157
+ description: string;
158
+ inputSchema: {
159
+ type: string;
160
+ properties: {
161
+ name: {
162
+ type: string;
163
+ description: string;
164
+ };
165
+ type: {
166
+ type: string;
167
+ description: string;
168
+ };
169
+ intent: {
170
+ type: string;
171
+ description: string;
172
+ };
173
+ file: {
174
+ type: string;
175
+ description: string;
176
+ };
177
+ cwd: {
178
+ type: "string";
179
+ description: string;
180
+ };
181
+ };
182
+ required: string[];
183
+ };
184
+ annotations: {
185
+ title: string;
186
+ readOnlyHint: boolean;
187
+ destructiveHint: boolean;
188
+ idempotentHint: boolean;
189
+ openWorldHint: boolean;
190
+ };
191
+ } | {
192
+ name: string;
193
+ description: string;
194
+ inputSchema: {
195
+ type: string;
196
+ properties: {
197
+ command: {
198
+ type: string;
199
+ description: string;
200
+ };
201
+ silent: {
202
+ type: string;
203
+ description: string;
204
+ };
205
+ cwd: {
206
+ type: "string";
207
+ description: string;
208
+ };
209
+ };
210
+ required: string[];
211
+ };
212
+ annotations: {
213
+ title: string;
214
+ readOnlyHint: boolean;
215
+ destructiveHint: boolean;
216
+ idempotentHint: boolean;
217
+ openWorldHint: boolean;
218
+ };
219
+ } | {
220
+ name: string;
221
+ description: string;
222
+ inputSchema: {
223
+ type: string;
224
+ properties: {
225
+ command: {
226
+ type: string;
227
+ description: string;
228
+ };
229
+ maxRetries: {
230
+ type: string;
231
+ description: string;
232
+ };
233
+ dryRun: {
234
+ type: string;
235
+ description: string;
236
+ };
237
+ cwd: {
238
+ type: "string";
239
+ description: string;
240
+ };
241
+ };
242
+ required: string[];
243
+ };
244
+ annotations: {
245
+ title: string;
246
+ readOnlyHint: boolean;
247
+ destructiveHint: boolean;
248
+ idempotentHint: boolean;
249
+ openWorldHint: boolean;
250
+ };
251
+ } | {
252
+ name: string;
253
+ description: string;
254
+ inputSchema: {
255
+ type: string;
256
+ properties: {
257
+ agentId: {
258
+ type: string;
259
+ description: string;
260
+ };
261
+ taskScope: {
262
+ type: string;
263
+ items: {
264
+ type: string;
265
+ };
266
+ description: string;
267
+ };
268
+ cwd: {
269
+ type: "string";
270
+ description: string;
271
+ };
272
+ };
273
+ required: string[];
274
+ };
275
+ annotations: {
276
+ title: string;
277
+ readOnlyHint: boolean;
278
+ destructiveHint: boolean;
279
+ idempotentHint: boolean;
280
+ openWorldHint: boolean;
281
+ };
282
+ } | {
283
+ name: string;
284
+ description: string;
285
+ inputSchema: {
286
+ type: string;
287
+ properties: {
288
+ progressPct: {
289
+ type: string;
290
+ description: string;
291
+ };
292
+ filesChanged: {
293
+ type: string;
294
+ items: {
295
+ type: string;
296
+ };
297
+ description: string;
298
+ };
299
+ summary: {
300
+ type: string;
301
+ description: string;
302
+ };
303
+ qualityScore: {
304
+ type: string;
305
+ description: string;
306
+ };
307
+ agentId: {
308
+ type: string;
309
+ description: string;
310
+ };
311
+ taskId: {
312
+ type: string;
313
+ description: string;
314
+ };
315
+ cwd: {
316
+ type: "string";
317
+ description: string;
318
+ };
319
+ };
320
+ required: string[];
321
+ };
322
+ annotations: {
323
+ title: string;
324
+ readOnlyHint: boolean;
325
+ destructiveHint: boolean;
326
+ idempotentHint: boolean;
327
+ openWorldHint: boolean;
328
+ };
329
+ } | {
330
+ name: string;
331
+ description: string;
332
+ inputSchema: {
333
+ type: string;
334
+ properties: {
335
+ fromAgentId: {
336
+ type: string;
337
+ description: string;
338
+ };
339
+ toAgentId: {
340
+ type: string;
341
+ description: string;
342
+ };
343
+ taskDescription: {
344
+ type: string;
345
+ description: string;
346
+ };
347
+ filesInScope: {
348
+ type: string;
349
+ items: {
350
+ type: string;
351
+ };
352
+ description: string;
353
+ };
354
+ context: {
355
+ type: string;
356
+ description: string;
357
+ };
358
+ cwd: {
359
+ type: "string";
360
+ description: string;
361
+ };
362
+ };
363
+ required: string[];
364
+ };
365
+ annotations: {
366
+ title: string;
367
+ readOnlyHint: boolean;
368
+ destructiveHint: boolean;
369
+ idempotentHint: boolean;
370
+ openWorldHint: boolean;
371
+ };
372
+ } | {
373
+ name: string;
374
+ description: string;
375
+ inputSchema: {
376
+ type: string;
377
+ properties: {
378
+ agentId: {
379
+ type: string;
380
+ description: string;
381
+ };
382
+ cwd: {
383
+ type: "string";
384
+ description: string;
385
+ };
386
+ };
387
+ required: string[];
388
+ };
389
+ annotations: {
390
+ title: string;
391
+ readOnlyHint: boolean;
392
+ destructiveHint: boolean;
393
+ idempotentHint: boolean;
394
+ openWorldHint: boolean;
395
+ };
396
+ } | {
397
+ name: string;
398
+ description: string;
399
+ inputSchema: {
400
+ type: string;
401
+ properties: {
402
+ handoffId: {
403
+ type: string;
404
+ description: string;
405
+ };
406
+ agentId: {
407
+ type: string;
408
+ description: string;
409
+ };
410
+ cwd: {
411
+ type: "string";
412
+ description: string;
413
+ };
414
+ };
415
+ required: string[];
416
+ };
417
+ annotations: {
418
+ title: string;
419
+ readOnlyHint: boolean;
420
+ destructiveHint: boolean;
421
+ idempotentHint: boolean;
422
+ openWorldHint: boolean;
423
+ };
424
+ } | {
425
+ name: string;
426
+ description: string;
427
+ inputSchema: {
428
+ type: string;
429
+ properties: {
430
+ files: {
431
+ type: string;
432
+ items: {
433
+ type: string;
434
+ };
435
+ description: string;
436
+ };
437
+ timeout: {
438
+ type: string;
439
+ description: string;
440
+ };
441
+ text: {
442
+ type: string;
443
+ description: string;
444
+ };
445
+ agent: {
446
+ type: string;
447
+ description: string;
448
+ };
449
+ cwd: {
450
+ type: "string";
451
+ description: string;
452
+ };
453
+ };
454
+ required: string[];
455
+ };
456
+ annotations: {
457
+ title: string;
458
+ readOnlyHint: boolean;
459
+ destructiveHint: boolean;
460
+ idempotentHint: boolean;
461
+ openWorldHint: boolean;
462
+ };
463
+ } | {
464
+ name: string;
465
+ description: string;
466
+ inputSchema: {
467
+ type: string;
468
+ properties: {
469
+ tool: {
470
+ type: string;
471
+ description: string;
472
+ };
473
+ force: {
474
+ type: string;
475
+ description: string;
476
+ };
477
+ dryRun: {
478
+ type: string;
479
+ description: string;
480
+ };
481
+ dlp: {
482
+ type: string;
483
+ description: string;
484
+ };
485
+ cwd: {
486
+ type: "string";
487
+ description: string;
488
+ };
489
+ };
490
+ required: string[];
491
+ };
492
+ annotations: {
493
+ title: string;
494
+ readOnlyHint: boolean;
495
+ destructiveHint: boolean;
496
+ idempotentHint: boolean;
497
+ openWorldHint: boolean;
498
+ };
499
+ } | {
500
+ name: string;
501
+ description: string;
502
+ inputSchema: {
503
+ type: string;
504
+ properties: {
505
+ pro: {
506
+ type: string;
507
+ description: string;
508
+ };
509
+ apiKey: {
510
+ type: string;
511
+ description: string;
512
+ };
513
+ provider: {
514
+ type: string;
515
+ description: string;
516
+ };
517
+ apiBaseUrl: {
518
+ type: string;
519
+ description: string;
520
+ };
521
+ modelName: {
522
+ type: string;
523
+ description: string;
524
+ };
525
+ cwd: {
526
+ type: "string";
527
+ description: string;
528
+ };
529
+ };
530
+ required: string[];
531
+ };
532
+ annotations: {
533
+ title: string;
534
+ readOnlyHint: boolean;
535
+ destructiveHint: boolean;
536
+ idempotentHint: boolean;
537
+ openWorldHint: boolean;
538
+ };
539
+ } | {
540
+ name: string;
541
+ description: string;
542
+ inputSchema: {
543
+ type: string;
544
+ properties: {
545
+ limit: {
546
+ type: string;
547
+ description: string;
548
+ };
549
+ cwd: {
550
+ type: "string";
551
+ description: string;
552
+ };
553
+ };
554
+ required: string[];
555
+ };
556
+ annotations: {
557
+ title: string;
558
+ readOnlyHint: boolean;
559
+ destructiveHint: boolean;
560
+ idempotentHint: boolean;
561
+ openWorldHint: boolean;
562
+ };
563
+ } | {
564
+ name: string;
565
+ description: string;
566
+ inputSchema: {
567
+ type: string;
568
+ properties: {
569
+ repository: {
570
+ type: string;
571
+ description: string;
572
+ };
573
+ branch: {
574
+ type: string;
575
+ description: string;
576
+ };
577
+ diff: {
578
+ type: string;
579
+ description: string;
580
+ };
581
+ files: {
582
+ type: string;
583
+ items: {
584
+ type: string;
585
+ };
586
+ description: string;
587
+ };
588
+ cwd: {
589
+ type: "string";
590
+ description: string;
591
+ };
592
+ };
593
+ required: string[];
594
+ };
595
+ annotations: {
596
+ title: string;
597
+ readOnlyHint: boolean;
598
+ destructiveHint: boolean;
599
+ idempotentHint: boolean;
600
+ openWorldHint: boolean;
601
+ };
602
+ } | {
603
+ name: string;
604
+ description: string;
605
+ inputSchema: {
606
+ type: string;
607
+ properties: {
608
+ taskId: {
609
+ type: string;
610
+ description: string;
611
+ };
612
+ cwd: {
613
+ type: "string";
614
+ description: string;
615
+ };
616
+ };
617
+ required: string[];
618
+ };
619
+ annotations: {
620
+ title: string;
621
+ readOnlyHint: boolean;
622
+ destructiveHint: boolean;
623
+ idempotentHint: boolean;
624
+ openWorldHint: boolean;
625
+ };
626
+ } | {
627
+ name: string;
628
+ description: string;
629
+ inputSchema: {
630
+ type: string;
631
+ properties: {
632
+ target: {
633
+ type: string;
634
+ description: string;
635
+ };
636
+ taskId: {
637
+ type: string;
638
+ description: string;
639
+ };
640
+ cwd: {
641
+ type: "string";
642
+ description: string;
643
+ };
644
+ };
645
+ required: string[];
646
+ };
647
+ annotations: {
648
+ title: string;
649
+ readOnlyHint: boolean;
650
+ destructiveHint: boolean;
651
+ idempotentHint: boolean;
652
+ openWorldHint: boolean;
653
+ };
654
+ } | {
655
+ name: string;
656
+ description: string;
657
+ inputSchema: {
658
+ type: string;
659
+ properties: {
660
+ semantic: {
661
+ type: string;
662
+ description: string;
663
+ };
664
+ force: {
665
+ type: string;
666
+ description: string;
667
+ };
668
+ output: {
669
+ type: string;
670
+ description: string;
671
+ };
672
+ cwd: {
673
+ type: "string";
674
+ description: string;
675
+ };
676
+ };
677
+ required: string[];
678
+ };
679
+ annotations: {
680
+ title: string;
681
+ readOnlyHint: boolean;
682
+ destructiveHint: boolean;
683
+ idempotentHint: boolean;
684
+ openWorldHint: boolean;
685
+ };
686
+ } | {
687
+ name: string;
688
+ description: string;
689
+ inputSchema: {
690
+ type: string;
691
+ properties: {
692
+ query: {
693
+ type: string;
694
+ description: string;
695
+ };
696
+ limit: {
697
+ type: string;
698
+ description: string;
699
+ };
700
+ taskId: {
701
+ type: string;
702
+ description: string;
703
+ };
704
+ agentId: {
705
+ type: string;
706
+ description: string;
707
+ };
708
+ cwd: {
709
+ type: "string";
710
+ description: string;
711
+ };
712
+ };
713
+ required: string[];
714
+ };
715
+ annotations: {
716
+ title: string;
717
+ readOnlyHint: boolean;
718
+ destructiveHint: boolean;
719
+ idempotentHint: boolean;
720
+ openWorldHint: boolean;
721
+ };
722
+ })[];
@@ -0,0 +1,46 @@
1
+ /**
2
+ * MCP tools advertised to clients via ListTools.
3
+ *
4
+ * Essential context/quality tools stay visible for day-to-day agent work.
5
+ * Governance tools are included so Cursor and other MCP clients can discover
6
+ * multi-agent registration, checkpoints, handoffs, hooks, and supervised runs
7
+ * without hunting for undocumented callable tools.
8
+ */
9
+ import { TOOL_DEFINITIONS } from './tools/definitions.js';
10
+ /** Context, quality, and cost telemetry tools every agent should see first. */
11
+ export const ESSENTIAL_CONTEXT_TOOLS = [
12
+ 'rigour_recall',
13
+ 'rigour_index',
14
+ 'rigour_context_scope',
15
+ 'rigour_check_pattern',
16
+ 'rigour_check',
17
+ 'rigour_remember',
18
+ 'rigour_explain',
19
+ 'rigour_get_fix_packet',
20
+ 'rigour_review',
21
+ 'rigour_security_audit',
22
+ 'rigour_forget',
23
+ 'rigour_context_stats',
24
+ 'rigour_task_cost',
25
+ 'rigour_cache_stats',
26
+ 'rigour_context_explain',
27
+ ];
28
+ /** Multi-agent governance, hooks, and execution tools with dispatch handlers. */
29
+ export const GOVERNANCE_TOOLS = [
30
+ 'rigour_agent_register',
31
+ 'rigour_agent_deregister',
32
+ 'rigour_checkpoint',
33
+ 'rigour_handoff',
34
+ 'rigour_handoff_accept',
35
+ 'rigour_hooks_check',
36
+ 'rigour_hooks_init',
37
+ 'rigour_run',
38
+ 'rigour_run_supervised',
39
+ ];
40
+ export const ADVERTISED_TOOLS = new Set([
41
+ ...ESSENTIAL_CONTEXT_TOOLS,
42
+ ...GOVERNANCE_TOOLS,
43
+ ]);
44
+ export function getAdvertisedToolDefinitions() {
45
+ return TOOL_DEFINITIONS.filter(t => ADVERTISED_TOOLS.has(t.name));
46
+ }
package/dist/index.js CHANGED
@@ -18,8 +18,8 @@ import { bindServer } from './utils/notifications.js';
18
18
  import { getMcpVersion } from './utils/package-version.js';
19
19
  // Dashboard (MCP App)
20
20
  import { DASHBOARD_URI, getDashboardHtml, pushTimelineEntry, updateScore } from './dashboard/index.js';
21
- // Tool definitions
22
- import { TOOL_DEFINITIONS } from './tools/definitions.js';
21
+ // Tool definitions & advertised registry
22
+ import { getAdvertisedToolDefinitions } from './advertised-tools.js';
23
23
  // Tool handlers
24
24
  import { handleCheck, handleExplain, handleStatus, handleGetFixPacket, handleListGates, handleGetConfig } from './tools/quality-handlers.js';
25
25
  import { handleRemember, handleRecall, handleForget } from './tools/memory-handlers.js';
@@ -38,28 +38,8 @@ const server = new Server({ name: "rigour-mcp", version: getMcpVersion('5.3.2')
38
38
  // Bind server for logging notifications from handlers
39
39
  bindServer(server);
40
40
  // ─── Tool Listing ─────────────────────────────────────────────────
41
- // Only expose essential tools by default to improve agent tool selection.
42
- // Research shows agents degrade at 30+ tools (wrong picks, hallucinated args).
43
- // Power-user tools are still callable — they just aren't advertised in the tool list.
44
- const ESSENTIAL_TOOLS = new Set([
45
- 'rigour_recall', // Load project memory (START of every task)
46
- 'rigour_index', // Build/refresh pattern index (if stale)
47
- 'rigour_context_scope', // Scoped file retrieval BEFORE reading files
48
- 'rigour_check_pattern', // Check if code exists (BEFORE creating new code)
49
- 'rigour_check', // Run quality gates (BEFORE declaring done)
50
- 'rigour_remember', // Store conventions/decisions
51
- 'rigour_explain', // Explain gate failures
52
- 'rigour_get_fix_packet', // Get structured fix instructions on FAIL
53
- 'rigour_review', // Review diffs
54
- 'rigour_security_audit', // CVE check
55
- 'rigour_forget', // Remove stored memory
56
- 'rigour_context_stats', // Context retrieval efficiency & avoided tokens
57
- 'rigour_task_cost', // Verified vs estimated avoided costs
58
- 'rigour_cache_stats', // 4-layer cache statistics
59
- 'rigour_context_explain', // Explain context inclusion/exclusion audit
60
- ]);
61
41
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
62
- tools: TOOL_DEFINITIONS.filter(t => ESSENTIAL_TOOLS.has(t.name)),
42
+ tools: getAdvertisedToolDefinitions(),
63
43
  }));
64
44
  // ─── Resource Listing (MCP App Dashboard) ────────────────────────
65
45
  server.setRequestHandler(ListResourcesRequestSchema, async () => ({
@@ -219,8 +199,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
219
199
  break;
220
200
  }
221
201
  case "rigour_context_scope": {
222
- const { query, limit } = args;
223
- result = await handleContextScope(cwd, query, limit);
202
+ const { query, limit, taskId, agentId } = args;
203
+ result = await handleContextScope(cwd, query, limit, taskId, agentId);
224
204
  break;
225
205
  }
226
206
  default:
@@ -231,15 +211,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
231
211
  const telemetry = result?._telemetry;
232
212
  const resultText = Array.isArray(result?.content) ? result.content.map((c) => c.text || '').join('\n') : '';
233
213
  const returnedTokens = telemetry?.returnedTokens ?? estimateTokenCount(resultText);
234
- await recordContextEvent({
235
- taskId: args?.taskId || args?.task_id,
236
- agentId: args?.agentId || args?.agent_id,
237
- toolName: name,
238
- cacheStatus: telemetry?.cacheStatus ?? 'none',
239
- candidateTokens: telemetry?.candidateTokens ?? returnedTokens,
240
- returnedTokens,
241
- deduplicatedTokens: telemetry?.deduplicatedTokens ?? 0,
242
- }, cwd);
214
+ if (!telemetry?.skipRecording) {
215
+ await recordContextEvent({
216
+ taskId: telemetry?.taskId
217
+ || args?.taskId
218
+ || args?.task_id,
219
+ agentId: telemetry?.agentId
220
+ || args?.agentId
221
+ || args?.agent_id,
222
+ toolName: name,
223
+ queryHash: telemetry?.queryHash,
224
+ cacheStatus: telemetry?.cacheStatus ?? 'none',
225
+ candidateTokens: telemetry?.candidateTokens ?? returnedTokens,
226
+ returnedTokens,
227
+ deduplicatedTokens: telemetry?.deduplicatedTokens ?? 0,
228
+ }, cwd);
229
+ }
243
230
  }
244
231
  catch {
245
232
  // non-blocking context telemetry logging
@@ -13,4 +13,4 @@ export declare function handleContextStats(cwd: string, taskId?: string): Promis
13
13
  export declare function handleTaskCost(cwd: string, taskId?: string): Promise<ToolResult>;
14
14
  export declare function handleCacheStats(cwd: string): Promise<ToolResult>;
15
15
  export declare function handleContextExplain(cwd: string, target: string, taskId?: string): Promise<ToolResult>;
16
- export declare function handleContextScope(cwd: string, query: string, limit?: number): Promise<ToolResult>;
16
+ export declare function handleContextScope(cwd: string, query: string, limit?: number, taskId?: string, agentId?: string): Promise<ToolResult>;
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import fs from 'fs-extra';
12
12
  import path from 'path';
13
+ import { createHash } from 'crypto';
13
14
  import { getTaskContextStats, getTaskCostStats, getCacheStats, explainContext, getSemanticQueryCache, setSemanticQueryCache, estimateTokenCount, } from '@rigour-labs/core';
14
15
  import { loadPatternIndex, getDefaultIndexPath, generateEmbedding, semanticSearch, } from '@rigour-labs/core/pattern-index';
15
16
  import { buildTelemetryMeta, getWorkspaceCommitSha } from '../utils/context-telemetry.js';
@@ -94,6 +95,20 @@ export async function handleContextExplain(cwd, target, taskId) {
94
95
  };
95
96
  }
96
97
  }
98
+ function hashScopeQuery(query) {
99
+ return createHash('sha256').update(query.trim().toLowerCase()).digest('hex').slice(0, 16);
100
+ }
101
+ function scopeTelemetryMeta(opts) {
102
+ return buildTelemetryMeta({
103
+ candidateText: opts.candidateText,
104
+ returnedText: opts.returnedText,
105
+ cacheStatus: opts.cacheStatus,
106
+ deduplicatedTokens: opts.deduplicatedTokens,
107
+ taskId: opts.taskId,
108
+ agentId: opts.agentId,
109
+ queryHash: hashScopeQuery(opts.query),
110
+ });
111
+ }
97
112
  function textMatchPatterns(query, patterns, limit) {
98
113
  const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
99
114
  const scored = patterns.map(p => {
@@ -107,17 +122,20 @@ function textMatchPatterns(query, patterns, limit) {
107
122
  .slice(0, limit)
108
123
  .map(s => s.pattern);
109
124
  }
110
- export async function handleContextScope(cwd, query, limit = 10) {
125
+ export async function handleContextScope(cwd, query, limit = 10, taskId, agentId) {
111
126
  const commitSha = await getWorkspaceCommitSha(cwd);
112
127
  const indexPath = getDefaultIndexPath(cwd);
113
128
  const fullIndexCandidate = `Full repository scan for: ${query}`;
114
129
  const cached = await getSemanticQueryCache(query, commitSha, cwd);
115
130
  if (cached) {
116
131
  const cachedText = JSON.stringify(cached, null, 2);
117
- const telemetry = buildTelemetryMeta({
132
+ const telemetry = scopeTelemetryMeta({
118
133
  candidateText: fullIndexCandidate,
119
134
  returnedText: cachedText,
120
135
  cacheStatus: 'semantic-hit',
136
+ query,
137
+ taskId,
138
+ agentId,
121
139
  });
122
140
  const text = `CONTEXT SCOPE (cached)\n\n${cachedText}`;
123
141
  return {
@@ -131,10 +149,13 @@ export async function handleContextScope(cwd, query, limit = 10) {
131
149
  + 'Without an index, agents tend to read entire directories — wasting tokens.';
132
150
  return {
133
151
  content: [{ type: 'text', text }],
134
- _telemetry: buildTelemetryMeta({
152
+ _telemetry: scopeTelemetryMeta({
135
153
  candidateText: fullIndexCandidate,
136
154
  returnedText: text,
137
155
  cacheStatus: 'miss',
156
+ query,
157
+ taskId,
158
+ agentId,
138
159
  }),
139
160
  };
140
161
  }
@@ -201,11 +222,14 @@ export async function handleContextScope(cwd, query, limit = 10) {
201
222
  confidence: matched.length > 0 ? 0.85 : 0.3,
202
223
  }, cwd);
203
224
  const resultText = JSON.stringify(scopePayload, null, 2);
204
- const telemetry = buildTelemetryMeta({
225
+ const telemetry = scopeTelemetryMeta({
205
226
  candidateText: fullIndexCandidate,
206
227
  returnedText: resultText,
207
228
  cacheStatus: 'miss',
208
229
  deduplicatedTokens: scopePayload.estimatedTokensSaved,
230
+ query,
231
+ taskId,
232
+ agentId,
209
233
  });
210
234
  return {
211
235
  content: [{
@@ -709,6 +709,14 @@ export declare const TOOL_DEFINITIONS: ({
709
709
  type: string;
710
710
  description: string;
711
711
  };
712
+ taskId: {
713
+ type: string;
714
+ description: string;
715
+ };
716
+ agentId: {
717
+ type: string;
718
+ description: string;
719
+ };
712
720
  cwd: {
713
721
  type: "string";
714
722
  description: string;
@@ -635,6 +635,8 @@ export const TOOL_DEFINITIONS = [
635
635
  ...cwdParam(),
636
636
  query: { type: "string", description: "Natural-language description of what you need to work on (e.g. 'add priority field to task service')." },
637
637
  limit: { type: "number", description: "Maximum number of pattern matches to return (default: 10)." },
638
+ taskId: { type: "string", description: "Optional task ID for context telemetry attribution." },
639
+ agentId: { type: "string", description: "Optional agent ID for context telemetry attribution." },
638
640
  },
639
641
  required: ["cwd", "query"],
640
642
  },
@@ -5,6 +5,10 @@ export type TelemetryMeta = {
5
5
  cacheStatus: CacheStatus;
6
6
  deduplicatedTokens?: number;
7
7
  isEstimated?: boolean;
8
+ taskId?: string;
9
+ agentId?: string;
10
+ queryHash?: string;
11
+ skipRecording?: boolean;
8
12
  };
9
13
  export type ToolResult = {
10
14
  content: {
@@ -22,6 +26,10 @@ export declare function buildTelemetryMeta(opts: {
22
26
  returnedText: string;
23
27
  cacheStatus: CacheStatus;
24
28
  deduplicatedTokens?: number;
29
+ taskId?: string;
30
+ agentId?: string;
31
+ queryHash?: string;
32
+ skipRecording?: boolean;
25
33
  }): TelemetryMeta;
26
34
  /** Resolve a short commit/ref fingerprint for cache keys. */
27
35
  export declare function getWorkspaceCommitSha(cwd: string): Promise<string>;
@@ -11,6 +11,10 @@ export function buildTelemetryMeta(opts) {
11
11
  cacheStatus: opts.cacheStatus,
12
12
  deduplicatedTokens: opts.deduplicatedTokens ?? 0,
13
13
  isEstimated: true,
14
+ taskId: opts.taskId,
15
+ agentId: opts.agentId,
16
+ queryHash: opts.queryHash,
17
+ skipRecording: opts.skipRecording,
14
18
  };
15
19
  }
16
20
  /** Resolve a short commit/ref fingerprint for cache keys. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/mcp",
3
- "version": "5.3.3",
3
+ "version": "5.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.2.0",
64
64
  "yaml": "^2.8.2",
65
- "@rigour-labs/core": "5.3.3"
65
+ "@rigour-labs/core": "5.4.0"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/node": "^25.0.3",