@bryan-thompson/inspector-assessment-client 1.6.0 → 1.7.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.
Files changed (74) hide show
  1. package/dist/assets/{OAuthCallback-ZcXdfhZQ.js → OAuthCallback-cGhwkoyY.js} +1 -1
  2. package/dist/assets/{OAuthDebugCallback-xt1SlIHS.js → OAuthDebugCallback-2rmUqser.js} +1 -1
  3. package/dist/assets/{index-B3lTiDVe.js → index-BnFixpvH.js} +4 -4
  4. package/dist/index.html +1 -1
  5. package/lib/lib/assessmentTypes.d.ts +670 -0
  6. package/lib/lib/assessmentTypes.d.ts.map +1 -0
  7. package/lib/lib/assessmentTypes.js +220 -0
  8. package/lib/lib/aupPatterns.d.ts +63 -0
  9. package/lib/lib/aupPatterns.d.ts.map +1 -0
  10. package/lib/lib/aupPatterns.js +344 -0
  11. package/lib/lib/prohibitedLibraries.d.ts +76 -0
  12. package/lib/lib/prohibitedLibraries.d.ts.map +1 -0
  13. package/lib/lib/prohibitedLibraries.js +364 -0
  14. package/lib/lib/securityPatterns.d.ts +64 -0
  15. package/lib/lib/securityPatterns.d.ts.map +1 -0
  16. package/lib/lib/securityPatterns.js +453 -0
  17. package/lib/services/assessment/AssessmentOrchestrator.d.ts +88 -0
  18. package/lib/services/assessment/AssessmentOrchestrator.d.ts.map +1 -0
  19. package/lib/services/assessment/AssessmentOrchestrator.js +418 -0
  20. package/lib/services/assessment/ResponseValidator.d.ts +69 -0
  21. package/lib/services/assessment/ResponseValidator.d.ts.map +1 -0
  22. package/lib/services/assessment/ResponseValidator.js +1038 -0
  23. package/lib/services/assessment/TestDataGenerator.d.ts +86 -0
  24. package/lib/services/assessment/TestDataGenerator.d.ts.map +1 -0
  25. package/lib/services/assessment/TestDataGenerator.js +669 -0
  26. package/lib/services/assessment/TestScenarioEngine.d.ts +91 -0
  27. package/lib/services/assessment/TestScenarioEngine.d.ts.map +1 -0
  28. package/lib/services/assessment/TestScenarioEngine.js +505 -0
  29. package/lib/services/assessment/ToolClassifier.d.ts +61 -0
  30. package/lib/services/assessment/ToolClassifier.d.ts.map +1 -0
  31. package/lib/services/assessment/ToolClassifier.js +349 -0
  32. package/lib/services/assessment/lib/claudeCodeBridge.d.ts +160 -0
  33. package/lib/services/assessment/lib/claudeCodeBridge.d.ts.map +1 -0
  34. package/lib/services/assessment/lib/claudeCodeBridge.js +357 -0
  35. package/lib/services/assessment/modules/AUPComplianceAssessor.d.ts +100 -0
  36. package/lib/services/assessment/modules/AUPComplianceAssessor.d.ts.map +1 -0
  37. package/lib/services/assessment/modules/AUPComplianceAssessor.js +474 -0
  38. package/lib/services/assessment/modules/BaseAssessor.d.ts +71 -0
  39. package/lib/services/assessment/modules/BaseAssessor.d.ts.map +1 -0
  40. package/lib/services/assessment/modules/BaseAssessor.js +171 -0
  41. package/lib/services/assessment/modules/DocumentationAssessor.d.ts +45 -0
  42. package/lib/services/assessment/modules/DocumentationAssessor.d.ts.map +1 -0
  43. package/lib/services/assessment/modules/DocumentationAssessor.js +355 -0
  44. package/lib/services/assessment/modules/ErrorHandlingAssessor.d.ts +25 -0
  45. package/lib/services/assessment/modules/ErrorHandlingAssessor.d.ts.map +1 -0
  46. package/lib/services/assessment/modules/ErrorHandlingAssessor.js +564 -0
  47. package/lib/services/assessment/modules/FunctionalityAssessor.d.ts +20 -0
  48. package/lib/services/assessment/modules/FunctionalityAssessor.d.ts.map +1 -0
  49. package/lib/services/assessment/modules/FunctionalityAssessor.js +253 -0
  50. package/lib/services/assessment/modules/MCPSpecComplianceAssessor.d.ts +70 -0
  51. package/lib/services/assessment/modules/MCPSpecComplianceAssessor.d.ts.map +1 -0
  52. package/lib/services/assessment/modules/MCPSpecComplianceAssessor.js +508 -0
  53. package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts +70 -0
  54. package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts.map +1 -0
  55. package/lib/services/assessment/modules/ManifestValidationAssessor.js +430 -0
  56. package/lib/services/assessment/modules/PortabilityAssessor.d.ts +43 -0
  57. package/lib/services/assessment/modules/PortabilityAssessor.d.ts.map +1 -0
  58. package/lib/services/assessment/modules/PortabilityAssessor.js +347 -0
  59. package/lib/services/assessment/modules/ProhibitedLibrariesAssessor.d.ts +41 -0
  60. package/lib/services/assessment/modules/ProhibitedLibrariesAssessor.d.ts.map +1 -0
  61. package/lib/services/assessment/modules/ProhibitedLibrariesAssessor.js +256 -0
  62. package/lib/services/assessment/modules/SecurityAssessor.d.ts +176 -0
  63. package/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -0
  64. package/lib/services/assessment/modules/SecurityAssessor.js +1333 -0
  65. package/lib/services/assessment/modules/ToolAnnotationAssessor.d.ts +96 -0
  66. package/lib/services/assessment/modules/ToolAnnotationAssessor.d.ts.map +1 -0
  67. package/lib/services/assessment/modules/ToolAnnotationAssessor.js +593 -0
  68. package/lib/services/assessment/modules/UsabilityAssessor.d.ts +21 -0
  69. package/lib/services/assessment/modules/UsabilityAssessor.d.ts.map +1 -0
  70. package/lib/services/assessment/modules/UsabilityAssessor.js +241 -0
  71. package/lib/services/assessment/modules/index.d.ts +33 -0
  72. package/lib/services/assessment/modules/index.d.ts.map +1 -0
  73. package/lib/services/assessment/modules/index.js +35 -0
  74. package/package.json +15 -3
@@ -0,0 +1,474 @@
1
+ /**
2
+ * AUP Compliance Assessor
3
+ * Scans MCP server for Acceptable Use Policy violations
4
+ *
5
+ * Checks:
6
+ * - Tool names and descriptions
7
+ * - README content
8
+ * - Source code (if sourceCodePath provided)
9
+ *
10
+ * Based on Anthropic's 14 AUP categories (A-N)
11
+ *
12
+ * Supports optional Claude Code integration for semantic analysis
13
+ * to reduce false positives (e.g., security tools, disclaimers).
14
+ */
15
+ import { BaseAssessor } from "./BaseAssessor.js";
16
+ import { checkTextForAUPViolations, checkTextForHighRiskDomains, } from "../../../lib/aupPatterns.js";
17
+ export class AUPComplianceAssessor extends BaseAssessor {
18
+ // Optional Claude Code bridge for semantic analysis
19
+ claudeBridge = null;
20
+ /**
21
+ * Set the Claude Code bridge for semantic violation analysis
22
+ */
23
+ setClaudeBridge(bridge) {
24
+ this.claudeBridge = bridge;
25
+ }
26
+ /**
27
+ * Check if Claude semantic analysis is enabled
28
+ */
29
+ isSemanticAnalysisEnabled() {
30
+ return (this.claudeBridge !== null &&
31
+ this.claudeBridge.isFeatureEnabled("aupSemanticAnalysis"));
32
+ }
33
+ /**
34
+ * Run AUP compliance assessment
35
+ * If Claude semantic analysis is enabled, violations are verified to reduce false positives.
36
+ */
37
+ async assess(context) {
38
+ this.log("Starting AUP compliance assessment");
39
+ this.testCount = 0;
40
+ const violations = [];
41
+ const highRiskDomains = [];
42
+ const scannedLocations = {
43
+ toolNames: false,
44
+ toolDescriptions: false,
45
+ readme: false,
46
+ sourceCode: false,
47
+ };
48
+ // Build a map of tool descriptions for semantic analysis context
49
+ const toolDescriptionMap = new Map();
50
+ for (const tool of context.tools) {
51
+ toolDescriptionMap.set(tool.name, tool.description || "");
52
+ }
53
+ // Scan tool names
54
+ this.log("Scanning tool names...");
55
+ scannedLocations.toolNames = true;
56
+ for (const tool of context.tools) {
57
+ this.testCount++;
58
+ const toolViolations = this.scanToolName(tool.name);
59
+ violations.push(...toolViolations);
60
+ // Check for high-risk domains
61
+ const domains = checkTextForHighRiskDomains(tool.name);
62
+ for (const domain of domains) {
63
+ if (!highRiskDomains.includes(domain.domain)) {
64
+ highRiskDomains.push(domain.domain);
65
+ }
66
+ }
67
+ }
68
+ // Scan tool descriptions
69
+ this.log("Scanning tool descriptions...");
70
+ scannedLocations.toolDescriptions = true;
71
+ for (const tool of context.tools) {
72
+ if (tool.description) {
73
+ this.testCount++;
74
+ const descViolations = this.scanToolDescription(tool.name, tool.description);
75
+ violations.push(...descViolations);
76
+ const domains = checkTextForHighRiskDomains(tool.description);
77
+ for (const domain of domains) {
78
+ if (!highRiskDomains.includes(domain.domain)) {
79
+ highRiskDomains.push(domain.domain);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ // Scan README content
85
+ if (context.readmeContent) {
86
+ this.log("Scanning README content...");
87
+ scannedLocations.readme = true;
88
+ this.testCount++;
89
+ const readmeViolations = this.scanReadme(context.readmeContent);
90
+ violations.push(...readmeViolations);
91
+ const domains = checkTextForHighRiskDomains(context.readmeContent);
92
+ for (const domain of domains) {
93
+ if (!highRiskDomains.includes(domain.domain)) {
94
+ highRiskDomains.push(domain.domain);
95
+ }
96
+ }
97
+ }
98
+ // Scan source code if available
99
+ if (context.sourceCodeFiles && context.config.enableSourceCodeAnalysis) {
100
+ this.log("Scanning source code files...");
101
+ scannedLocations.sourceCode = true;
102
+ for (const [filePath, content] of context.sourceCodeFiles) {
103
+ // Skip non-relevant files
104
+ if (this.shouldSkipFile(filePath))
105
+ continue;
106
+ this.testCount++;
107
+ const sourceViolations = this.scanSourceFile(filePath, content);
108
+ violations.push(...sourceViolations);
109
+ }
110
+ }
111
+ // If Claude semantic analysis is enabled, verify violations to reduce false positives
112
+ if (this.isSemanticAnalysisEnabled() && violations.length > 0) {
113
+ this.log(`Running semantic analysis on ${violations.length} potential violations...`);
114
+ return await this.runSemanticAnalysis(violations, highRiskDomains, scannedLocations, toolDescriptionMap);
115
+ }
116
+ // Standard assessment without semantic analysis
117
+ const status = this.determineAUPStatus(violations);
118
+ const explanation = this.generateExplanation(violations, highRiskDomains, scannedLocations);
119
+ const recommendations = this.generateRecommendations(violations, highRiskDomains);
120
+ this.log(`Assessment complete: ${violations.length} violations found, ${highRiskDomains.length} high-risk domains`);
121
+ return {
122
+ violations,
123
+ highRiskDomains,
124
+ scannedLocations,
125
+ status,
126
+ explanation,
127
+ recommendations,
128
+ };
129
+ }
130
+ /**
131
+ * Run Claude semantic analysis on flagged violations
132
+ * Separates confirmed violations from likely false positives
133
+ */
134
+ async runSemanticAnalysis(violations, highRiskDomains, scannedLocations, toolDescriptionMap) {
135
+ const confirmedViolations = [];
136
+ const flaggedForReview = [];
137
+ let falsePositivesFiltered = 0;
138
+ // Analyze each violation with Claude
139
+ for (const violation of violations) {
140
+ try {
141
+ // Get tool description for context
142
+ const toolDescription = violation.location === "tool_name" ||
143
+ violation.location === "tool_description"
144
+ ? toolDescriptionMap.get(violation.matchedText.split(" ")[0]) || ""
145
+ : "";
146
+ const analysis = await this.claudeBridge.analyzeAUPViolation(violation.matchedText, {
147
+ toolName: violation.location === "tool_name"
148
+ ? violation.matchedText
149
+ : "unknown",
150
+ toolDescription,
151
+ category: violation.category,
152
+ categoryName: violation.categoryName,
153
+ location: violation.location,
154
+ });
155
+ // Handle null result (Claude unavailable or error)
156
+ if (!analysis) {
157
+ flaggedForReview.push({
158
+ ...violation,
159
+ semanticAnalysis: {
160
+ isConfirmedViolation: true,
161
+ confidence: 50,
162
+ reasoning: "Claude analysis unavailable. Flagged for manual review.",
163
+ source: "pattern-only",
164
+ },
165
+ });
166
+ continue;
167
+ }
168
+ const enhancedViolation = {
169
+ ...violation,
170
+ semanticAnalysis: {
171
+ isConfirmedViolation: analysis.isViolation,
172
+ confidence: analysis.confidence,
173
+ reasoning: analysis.reasoning,
174
+ source: "claude-verified",
175
+ },
176
+ };
177
+ // High confidence confirmed violations
178
+ if (analysis.isViolation && analysis.confidence >= 70) {
179
+ confirmedViolations.push(enhancedViolation);
180
+ }
181
+ // Uncertain - flag for human review
182
+ else if (analysis.isViolation || analysis.confidence >= 40) {
183
+ flaggedForReview.push(enhancedViolation);
184
+ }
185
+ // Low confidence - likely false positive
186
+ else {
187
+ falsePositivesFiltered++;
188
+ this.log(`Filtered likely false positive: "${violation.matchedText}" - ${analysis.reasoning}`);
189
+ }
190
+ }
191
+ catch (error) {
192
+ // On analysis error, conservatively add to flagged for review
193
+ flaggedForReview.push({
194
+ ...violation,
195
+ semanticAnalysis: {
196
+ isConfirmedViolation: true,
197
+ confidence: 50,
198
+ reasoning: `Analysis error: ${error}. Flagged for manual review.`,
199
+ source: "pattern-only",
200
+ },
201
+ });
202
+ }
203
+ }
204
+ // Determine status based on confirmed violations only
205
+ const status = this.determineAUPStatus(confirmedViolations);
206
+ const explanation = this.generateSemanticExplanation(confirmedViolations, flaggedForReview, falsePositivesFiltered, highRiskDomains, scannedLocations);
207
+ const recommendations = this.generateSemanticRecommendations(confirmedViolations, flaggedForReview, highRiskDomains);
208
+ this.log(`Semantic analysis complete: ${confirmedViolations.length} confirmed, ${flaggedForReview.length} flagged, ${falsePositivesFiltered} filtered`);
209
+ return {
210
+ violations: [...confirmedViolations, ...flaggedForReview],
211
+ confirmedViolations,
212
+ flaggedForReview,
213
+ highRiskDomains,
214
+ scannedLocations,
215
+ status,
216
+ explanation,
217
+ recommendations,
218
+ semanticAnalysisEnabled: true,
219
+ falsePositivesFiltered,
220
+ };
221
+ }
222
+ /**
223
+ * Generate explanation for semantic analysis results
224
+ */
225
+ generateSemanticExplanation(confirmed, flagged, filtered, highRiskDomains, scannedLocations) {
226
+ const parts = [];
227
+ parts.push(`Semantic analysis enabled (Claude-verified). ${filtered} likely false positives filtered.`);
228
+ if (confirmed.length === 0 && flagged.length === 0) {
229
+ parts.push("No AUP violations confirmed after semantic analysis.");
230
+ }
231
+ else {
232
+ if (confirmed.length > 0) {
233
+ const criticalCount = confirmed.filter((v) => v.severity === "CRITICAL").length;
234
+ const highCount = confirmed.filter((v) => v.severity === "HIGH").length;
235
+ if (criticalCount > 0) {
236
+ parts.push(`CRITICAL: ${criticalCount} confirmed critical violation(s).`);
237
+ }
238
+ if (highCount > 0) {
239
+ parts.push(`HIGH: ${highCount} confirmed high-severity violation(s).`);
240
+ }
241
+ }
242
+ if (flagged.length > 0) {
243
+ parts.push(`${flagged.length} item(s) flagged for manual review.`);
244
+ }
245
+ }
246
+ if (highRiskDomains.length > 0) {
247
+ parts.push(`High-risk domains: ${highRiskDomains.join(", ")}. Additional review recommended.`);
248
+ }
249
+ const scannedList = Object.entries(scannedLocations)
250
+ .filter(([, scanned]) => scanned)
251
+ .map(([location]) => location);
252
+ parts.push(`Scanned: ${scannedList.join(", ")}.`);
253
+ return parts.join(" ");
254
+ }
255
+ /**
256
+ * Generate recommendations for semantic analysis results
257
+ */
258
+ generateSemanticRecommendations(confirmed, flagged, highRiskDomains) {
259
+ const recommendations = [];
260
+ // Confirmed violations
261
+ if (confirmed.length > 0) {
262
+ const criticalViolations = confirmed.filter((v) => v.severity === "CRITICAL");
263
+ if (criticalViolations.length > 0) {
264
+ recommendations.push("CRITICAL (Claude-verified): This MCP server contains content that violates Anthropic's Acceptable Use Policy:");
265
+ for (const v of criticalViolations) {
266
+ recommendations.push(`- Category ${v.category} (${v.categoryName}): "${v.matchedText}" - ${v.semanticAnalysis?.reasoning || ""}`);
267
+ }
268
+ }
269
+ const highViolations = confirmed.filter((v) => v.severity === "HIGH");
270
+ if (highViolations.length > 0) {
271
+ recommendations.push("HIGH (Claude-verified): Confirmed AUP violations:");
272
+ for (const v of highViolations) {
273
+ recommendations.push(`- Category ${v.category} (${v.categoryName}): "${v.matchedText}" - ${v.semanticAnalysis?.reasoning || ""}`);
274
+ }
275
+ }
276
+ }
277
+ // Flagged for review
278
+ if (flagged.length > 0) {
279
+ recommendations.push("MANUAL REVIEW REQUIRED: The following items need human verification:");
280
+ for (const v of flagged) {
281
+ recommendations.push(`- Category ${v.category}: "${v.matchedText}" (${v.semanticAnalysis?.confidence || 50}% confidence) - ${v.semanticAnalysis?.reasoning || ""}`);
282
+ }
283
+ }
284
+ // High-risk domains
285
+ if (highRiskDomains.length > 0) {
286
+ recommendations.push(`This server operates in high-risk domain(s): ${highRiskDomains.join(", ")}. Ensure appropriate safeguards.`);
287
+ }
288
+ // If no issues
289
+ if (recommendations.length === 0) {
290
+ recommendations.push("No AUP compliance issues confirmed after semantic analysis. Server appears compliant with Anthropic's Acceptable Use Policy.");
291
+ }
292
+ return recommendations;
293
+ }
294
+ /**
295
+ * Scan a tool name for AUP violations
296
+ */
297
+ scanToolName(toolName) {
298
+ const matches = checkTextForAUPViolations(toolName);
299
+ return matches.map((match) => ({
300
+ category: match.category,
301
+ categoryName: match.categoryName,
302
+ severity: match.severity,
303
+ pattern: match.matchedPattern,
304
+ matchedText: match.matchedText,
305
+ location: "tool_name",
306
+ confidence: "high",
307
+ requiresHumanReview: match.requiresHumanReview,
308
+ reviewGuidance: match.reviewGuidance,
309
+ }));
310
+ }
311
+ /**
312
+ * Scan a tool description for AUP violations
313
+ */
314
+ scanToolDescription(toolName, description) {
315
+ const matches = checkTextForAUPViolations(description);
316
+ return matches.map((match) => ({
317
+ category: match.category,
318
+ categoryName: match.categoryName,
319
+ severity: match.severity,
320
+ pattern: match.matchedPattern,
321
+ matchedText: match.matchedText,
322
+ location: "tool_description",
323
+ confidence: "medium", // Descriptions can have legitimate context
324
+ requiresHumanReview: match.requiresHumanReview,
325
+ reviewGuidance: `Tool: ${toolName}. ${match.reviewGuidance || ""}`,
326
+ }));
327
+ }
328
+ /**
329
+ * Scan README content for AUP violations
330
+ */
331
+ scanReadme(content) {
332
+ const matches = checkTextForAUPViolations(content);
333
+ return matches.map((match) => ({
334
+ category: match.category,
335
+ categoryName: match.categoryName,
336
+ severity: match.severity,
337
+ pattern: match.matchedPattern,
338
+ matchedText: match.matchedText,
339
+ location: "readme",
340
+ confidence: "low", // READMEs often discuss what NOT to do
341
+ requiresHumanReview: true,
342
+ reviewGuidance: `README match - verify context. ${match.reviewGuidance || ""}`,
343
+ }));
344
+ }
345
+ /**
346
+ * Scan a source file for AUP violations
347
+ */
348
+ scanSourceFile(filePath, content) {
349
+ const violations = [];
350
+ const lines = content.split("\n");
351
+ for (let i = 0; i < lines.length; i++) {
352
+ const line = lines[i];
353
+ const matches = checkTextForAUPViolations(line);
354
+ for (const match of matches) {
355
+ violations.push({
356
+ category: match.category,
357
+ categoryName: match.categoryName,
358
+ severity: match.severity,
359
+ pattern: match.matchedPattern,
360
+ matchedText: match.matchedText,
361
+ location: "source_code",
362
+ filePath,
363
+ lineNumber: i + 1,
364
+ confidence: "medium",
365
+ requiresHumanReview: match.requiresHumanReview,
366
+ reviewGuidance: match.reviewGuidance,
367
+ });
368
+ }
369
+ }
370
+ return violations;
371
+ }
372
+ /**
373
+ * Check if a file should be skipped for AUP scanning
374
+ */
375
+ shouldSkipFile(filePath) {
376
+ const skipPatterns = [
377
+ /node_modules/,
378
+ /\.test\.(ts|js|tsx|jsx)$/,
379
+ /\.spec\.(ts|js|tsx|jsx)$/,
380
+ /\.d\.ts$/,
381
+ /package-lock\.json$/,
382
+ /yarn\.lock$/,
383
+ /\.map$/,
384
+ /\.min\.(js|css)$/,
385
+ ];
386
+ return skipPatterns.some((pattern) => pattern.test(filePath));
387
+ }
388
+ /**
389
+ * Determine overall status based on violations
390
+ */
391
+ determineAUPStatus(violations) {
392
+ // CRITICAL violations = automatic FAIL
393
+ const criticalViolations = violations.filter((v) => v.severity === "CRITICAL");
394
+ if (criticalViolations.length > 0) {
395
+ return "FAIL";
396
+ }
397
+ // HIGH violations = FAIL unless all low confidence
398
+ const highViolations = violations.filter((v) => v.severity === "HIGH");
399
+ const highConfidenceHigh = highViolations.filter((v) => v.confidence === "high" || v.confidence === "medium");
400
+ if (highConfidenceHigh.length > 0) {
401
+ return "FAIL";
402
+ }
403
+ // MEDIUM/FLAG violations = NEED_MORE_INFO
404
+ if (violations.length > 0) {
405
+ return "NEED_MORE_INFO";
406
+ }
407
+ return "PASS";
408
+ }
409
+ /**
410
+ * Generate explanation text
411
+ */
412
+ generateExplanation(violations, highRiskDomains, scannedLocations) {
413
+ const parts = [];
414
+ // Summary
415
+ if (violations.length === 0 && highRiskDomains.length === 0) {
416
+ parts.push("No AUP violations detected.");
417
+ }
418
+ else {
419
+ const criticalCount = violations.filter((v) => v.severity === "CRITICAL").length;
420
+ const highCount = violations.filter((v) => v.severity === "HIGH").length;
421
+ const mediumCount = violations.filter((v) => v.severity === "MEDIUM").length;
422
+ if (criticalCount > 0) {
423
+ parts.push(`CRITICAL: ${criticalCount} critical AUP violation(s) detected that require immediate review.`);
424
+ }
425
+ if (highCount > 0) {
426
+ parts.push(`HIGH: ${highCount} high-severity violation(s) detected.`);
427
+ }
428
+ if (mediumCount > 0) {
429
+ parts.push(`MEDIUM: ${mediumCount} medium-severity item(s) flagged for review.`);
430
+ }
431
+ }
432
+ // High-risk domains
433
+ if (highRiskDomains.length > 0) {
434
+ parts.push(`High-risk domains detected: ${highRiskDomains.join(", ")}. Additional review recommended.`);
435
+ }
436
+ // Coverage
437
+ const scannedList = Object.entries(scannedLocations)
438
+ .filter(([, scanned]) => scanned)
439
+ .map(([location]) => location);
440
+ parts.push(`Scanned: ${scannedList.join(", ")}.`);
441
+ return parts.join(" ");
442
+ }
443
+ /**
444
+ * Generate recommendations
445
+ */
446
+ generateRecommendations(violations, highRiskDomains) {
447
+ const recommendations = [];
448
+ // Critical violations
449
+ const criticalViolations = violations.filter((v) => v.severity === "CRITICAL");
450
+ if (criticalViolations.length > 0) {
451
+ recommendations.push("CRITICAL: This MCP server contains content that violates Anthropic's Acceptable Use Policy and cannot be approved for the directory.");
452
+ for (const v of criticalViolations) {
453
+ recommendations.push(`- Category ${v.category} (${v.categoryName}): "${v.matchedText}" in ${v.location}`);
454
+ }
455
+ }
456
+ // High violations
457
+ const highViolations = violations.filter((v) => v.severity === "HIGH");
458
+ if (highViolations.length > 0) {
459
+ recommendations.push("HIGH: Review the following items for potential AUP violations:");
460
+ for (const v of highViolations) {
461
+ recommendations.push(`- Category ${v.category} (${v.categoryName}): "${v.matchedText}" in ${v.location}`);
462
+ }
463
+ }
464
+ // High-risk domains
465
+ if (highRiskDomains.length > 0) {
466
+ recommendations.push(`This server operates in high-risk domain(s): ${highRiskDomains.join(", ")}. Ensure appropriate safeguards and human oversight are in place.`);
467
+ }
468
+ // If no issues
469
+ if (recommendations.length === 0) {
470
+ recommendations.push("No AUP compliance issues detected. Server appears compliant with Anthropic's Acceptable Use Policy.");
471
+ }
472
+ return recommendations;
473
+ }
474
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Base Assessor Class
3
+ * Provides common functionality for all assessment modules
4
+ */
5
+ import { AssessmentConfiguration, AssessmentStatus } from "../../../lib/assessmentTypes.js";
6
+ import { AssessmentContext } from "../AssessmentOrchestrator.js";
7
+ export declare abstract class BaseAssessor {
8
+ protected config: AssessmentConfiguration;
9
+ protected testCount: number;
10
+ constructor(config: AssessmentConfiguration);
11
+ /**
12
+ * Abstract method that each assessor must implement
13
+ */
14
+ abstract assess(context: AssessmentContext): Promise<any>;
15
+ /**
16
+ * Common method to determine status based on pass rate
17
+ */
18
+ protected determineStatus(passed: number, total: number, threshold?: number): AssessmentStatus;
19
+ /**
20
+ * Log assessment progress
21
+ */
22
+ protected log(message: string): void;
23
+ /**
24
+ * Log error
25
+ */
26
+ protected logError(message: string, error?: any): void;
27
+ /**
28
+ * Get test count for this assessor
29
+ */
30
+ getTestCount(): number;
31
+ /**
32
+ * Reset test count
33
+ */
34
+ resetTestCount(): void;
35
+ /**
36
+ * Check if a feature is enabled in configuration
37
+ */
38
+ protected isFeatureEnabled(feature: keyof AssessmentConfiguration["assessmentCategories"]): boolean;
39
+ /**
40
+ * Sleep for specified milliseconds (useful for rate limiting)
41
+ */
42
+ protected sleep(ms: number): Promise<void>;
43
+ /**
44
+ * Execute with timeout
45
+ */
46
+ protected executeWithTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T>;
47
+ /**
48
+ * Safe JSON parse with error handling
49
+ */
50
+ protected safeJsonParse(text: string): any;
51
+ /**
52
+ * Extract error message from various error types
53
+ */
54
+ protected extractErrorMessage(error: any): string;
55
+ /**
56
+ * Check if a response indicates an error
57
+ * Handles various MCP response formats
58
+ *
59
+ * @param response - The response to check
60
+ * @param strictMode - If true, only check explicit error indicators (default: false)
61
+ */
62
+ protected isErrorResponse(response: any, strictMode?: boolean): boolean;
63
+ /**
64
+ * Extract error information from a response
65
+ */
66
+ protected extractErrorInfo(response: any): {
67
+ code?: string | number;
68
+ message?: string;
69
+ };
70
+ }
71
+ //# sourceMappingURL=BaseAssessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/BaseAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,8BAAsB,YAAY;IAChC,SAAS,CAAC,MAAM,EAAE,uBAAuB,CAAC;IAC1C,SAAS,CAAC,SAAS,EAAE,MAAM,CAAK;gBAEpB,MAAM,EAAE,uBAAuB;IAI3C;;OAEG;IACH,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,eAAe,CACvB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAY,GACtB,gBAAgB;IAUnB;;OAEG;IACH,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,IAAI;IAItD;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,SAAS,CAAC,gBAAgB,CACxB,OAAO,EAAE,MAAM,uBAAuB,CAAC,sBAAsB,CAAC,GAC7D,OAAO;IAIV;;OAEG;cACa,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD;;OAEG;cACa,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,GAAE,MAAgC,GAC1C,OAAO,CAAC,CAAC,CAAC;IAWb;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG;IAS1C;;OAEG;IACH,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM;IAejD;;;;;;OAMG;IACH,SAAS,CAAC,eAAe,CACvB,QAAQ,EAAE,GAAG,EACb,UAAU,GAAE,OAAe,GAC1B,OAAO;IA8CV;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG;QACzC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;CAqBF"}