@bryan-thompson/inspector-assessment-client 1.13.0 → 1.14.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/assets/{OAuthCallback-D8KW6pFf.js → OAuthCallback-DaKwjxdn.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-D15nNAOl.js → OAuthDebugCallback-HiI2IPgB.js} +1 -1
- package/dist/assets/{index-cVkEgqCc.js → index-BAJG90Yd.js} +20 -8
- package/dist/assets/{index-Cuc9GxjD.css → index-BdXNC65t.css} +3 -0
- package/dist/index.html +2 -2
- package/lib/lib/assessmentDiffer.d.ts +79 -0
- package/lib/lib/assessmentDiffer.d.ts.map +1 -0
- package/lib/lib/assessmentDiffer.js +289 -0
- package/lib/lib/assessmentTypes.d.ts +69 -0
- package/lib/lib/assessmentTypes.d.ts.map +1 -1
- package/lib/lib/assessmentTypes.js +10 -0
- package/lib/lib/reportFormatters/DiffReportFormatter.d.ts +10 -0
- package/lib/lib/reportFormatters/DiffReportFormatter.d.ts.map +1 -0
- package/lib/lib/reportFormatters/DiffReportFormatter.js +177 -0
- package/lib/services/assessment/AssessmentOrchestrator.d.ts +1 -0
- package/lib/services/assessment/AssessmentOrchestrator.d.ts.map +1 -1
- package/lib/services/assessment/AssessmentOrchestrator.js +22 -1
- package/lib/services/assessment/modules/AuthenticationAssessor.d.ts +48 -0
- package/lib/services/assessment/modules/AuthenticationAssessor.d.ts.map +1 -0
- package/lib/services/assessment/modules/AuthenticationAssessor.js +270 -0
- package/lib/services/assessment/modules/ExternalAPIScannerAssessor.d.ts +58 -0
- package/lib/services/assessment/modules/ExternalAPIScannerAssessor.d.ts.map +1 -0
- package/lib/services/assessment/modules/ExternalAPIScannerAssessor.js +248 -0
- package/lib/services/assessment/modules/FunctionalityAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/FunctionalityAssessor.js +7 -0
- package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts +4 -0
- package/lib/services/assessment/modules/ManifestValidationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ManifestValidationAssessor.js +118 -4
- package/lib/services/assessment/modules/index.d.ts +1 -0
- package/lib/services/assessment/modules/index.d.ts.map +1 -1
- package/lib/services/assessment/modules/index.js +1 -0
- package/package.json +1 -1
|
@@ -86,9 +86,41 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
86
86
|
// Validate version format
|
|
87
87
|
this.testCount++;
|
|
88
88
|
validationResults.push(this.validateVersionFormat(manifest.version));
|
|
89
|
+
// Validate privacy policy URLs if present
|
|
90
|
+
let privacyPolicies;
|
|
91
|
+
if (manifest.privacy_policies &&
|
|
92
|
+
Array.isArray(manifest.privacy_policies) &&
|
|
93
|
+
manifest.privacy_policies.length > 0) {
|
|
94
|
+
this.log(`Validating ${manifest.privacy_policies.length} privacy policy URL(s)`);
|
|
95
|
+
const policyResults = await this.validatePrivacyPolicyUrls(manifest.privacy_policies);
|
|
96
|
+
privacyPolicies = {
|
|
97
|
+
declared: manifest.privacy_policies,
|
|
98
|
+
validationResults: policyResults,
|
|
99
|
+
allAccessible: policyResults.every((r) => r.accessible),
|
|
100
|
+
};
|
|
101
|
+
// Add validation result for privacy policies
|
|
102
|
+
if (!privacyPolicies.allAccessible) {
|
|
103
|
+
const inaccessible = policyResults.filter((r) => !r.accessible);
|
|
104
|
+
validationResults.push({
|
|
105
|
+
field: "privacy_policies",
|
|
106
|
+
valid: false,
|
|
107
|
+
value: manifest.privacy_policies,
|
|
108
|
+
issue: `${inaccessible.length}/${policyResults.length} privacy policy URL(s) inaccessible`,
|
|
109
|
+
severity: "WARNING",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
validationResults.push({
|
|
114
|
+
field: "privacy_policies",
|
|
115
|
+
valid: true,
|
|
116
|
+
value: manifest.privacy_policies,
|
|
117
|
+
severity: "INFO",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
89
121
|
const status = this.determineManifestStatus(validationResults, hasRequiredFields);
|
|
90
|
-
const explanation = this.generateExplanation(validationResults, hasRequiredFields, hasIcon);
|
|
91
|
-
const recommendations = this.generateRecommendations(validationResults);
|
|
122
|
+
const explanation = this.generateExplanation(validationResults, hasRequiredFields, hasIcon, privacyPolicies);
|
|
123
|
+
const recommendations = this.generateRecommendations(validationResults, privacyPolicies);
|
|
92
124
|
this.log(`Assessment complete: ${validationResults.filter((r) => r.valid).length}/${validationResults.length} checks passed`);
|
|
93
125
|
return {
|
|
94
126
|
hasManifest: true,
|
|
@@ -97,6 +129,7 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
97
129
|
hasIcon,
|
|
98
130
|
hasRequiredFields,
|
|
99
131
|
missingFields,
|
|
132
|
+
privacyPolicies,
|
|
100
133
|
status,
|
|
101
134
|
explanation,
|
|
102
135
|
recommendations,
|
|
@@ -368,6 +401,73 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
368
401
|
severity: "INFO",
|
|
369
402
|
};
|
|
370
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Validate privacy policy URLs are accessible
|
|
406
|
+
*/
|
|
407
|
+
async validatePrivacyPolicyUrls(privacyPolicies) {
|
|
408
|
+
const results = [];
|
|
409
|
+
for (const url of privacyPolicies) {
|
|
410
|
+
this.testCount++;
|
|
411
|
+
// Validate URL format first
|
|
412
|
+
try {
|
|
413
|
+
new URL(url);
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
results.push({
|
|
417
|
+
url,
|
|
418
|
+
accessible: false,
|
|
419
|
+
error: "Invalid URL format",
|
|
420
|
+
});
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
// Use HEAD request for efficiency, fallback to GET if needed
|
|
425
|
+
const controller = new AbortController();
|
|
426
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
427
|
+
const response = await fetch(url, {
|
|
428
|
+
method: "HEAD",
|
|
429
|
+
signal: controller.signal,
|
|
430
|
+
redirect: "follow",
|
|
431
|
+
});
|
|
432
|
+
clearTimeout(timeoutId);
|
|
433
|
+
results.push({
|
|
434
|
+
url,
|
|
435
|
+
accessible: response.ok,
|
|
436
|
+
statusCode: response.status,
|
|
437
|
+
contentType: response.headers.get("content-type") || undefined,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
// Try GET request as fallback (some servers reject HEAD)
|
|
442
|
+
try {
|
|
443
|
+
const controller = new AbortController();
|
|
444
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
445
|
+
const response = await fetch(url, {
|
|
446
|
+
method: "GET",
|
|
447
|
+
signal: controller.signal,
|
|
448
|
+
redirect: "follow",
|
|
449
|
+
});
|
|
450
|
+
clearTimeout(timeoutId);
|
|
451
|
+
results.push({
|
|
452
|
+
url,
|
|
453
|
+
accessible: response.ok,
|
|
454
|
+
statusCode: response.status,
|
|
455
|
+
contentType: response.headers.get("content-type") || undefined,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
catch (fetchError) {
|
|
459
|
+
results.push({
|
|
460
|
+
url,
|
|
461
|
+
accessible: false,
|
|
462
|
+
error: fetchError instanceof Error
|
|
463
|
+
? fetchError.message
|
|
464
|
+
: "Network error",
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return results;
|
|
470
|
+
}
|
|
371
471
|
/**
|
|
372
472
|
* Determine overall status
|
|
373
473
|
*/
|
|
@@ -385,7 +485,7 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
385
485
|
/**
|
|
386
486
|
* Generate explanation
|
|
387
487
|
*/
|
|
388
|
-
generateExplanation(results, hasRequiredFields, hasIcon) {
|
|
488
|
+
generateExplanation(results, hasRequiredFields, hasIcon, privacyPolicies) {
|
|
389
489
|
const parts = [];
|
|
390
490
|
const passed = results.filter((r) => r.valid).length;
|
|
391
491
|
const total = results.length;
|
|
@@ -396,6 +496,10 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
396
496
|
if (!hasIcon) {
|
|
397
497
|
parts.push("No icon found - recommended for MCPB bundles.");
|
|
398
498
|
}
|
|
499
|
+
if (privacyPolicies && !privacyPolicies.allAccessible) {
|
|
500
|
+
const inaccessible = privacyPolicies.validationResults.filter((r) => !r.accessible);
|
|
501
|
+
parts.push(`${inaccessible.length} privacy policy URL(s) are inaccessible.`);
|
|
502
|
+
}
|
|
399
503
|
const errors = results.filter((r) => !r.valid && r.severity === "ERROR");
|
|
400
504
|
if (errors.length > 0) {
|
|
401
505
|
parts.push(`${errors.length} error(s) require attention.`);
|
|
@@ -405,7 +509,7 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
405
509
|
/**
|
|
406
510
|
* Generate recommendations
|
|
407
511
|
*/
|
|
408
|
-
generateRecommendations(results) {
|
|
512
|
+
generateRecommendations(results, privacyPolicies) {
|
|
409
513
|
const recommendations = [];
|
|
410
514
|
// Group by severity
|
|
411
515
|
const errors = results.filter((r) => !r.valid && r.severity === "ERROR");
|
|
@@ -422,6 +526,16 @@ export class ManifestValidationAssessor extends BaseAssessor {
|
|
|
422
526
|
recommendations.push(`- ${warning.field}: ${warning.issue}`);
|
|
423
527
|
}
|
|
424
528
|
}
|
|
529
|
+
// Add privacy policy recommendations
|
|
530
|
+
if (privacyPolicies && !privacyPolicies.allAccessible) {
|
|
531
|
+
recommendations.push("PRIVACY POLICY - Fix inaccessible URLs:");
|
|
532
|
+
for (const result of privacyPolicies.validationResults) {
|
|
533
|
+
if (!result.accessible) {
|
|
534
|
+
const reason = result.error || `HTTP ${result.statusCode}`;
|
|
535
|
+
recommendations.push(`- ${result.url}: ${reason}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
425
539
|
if (recommendations.length === 0) {
|
|
426
540
|
recommendations.push("Manifest validation passed. All required fields are present and valid.");
|
|
427
541
|
}
|
|
@@ -30,4 +30,5 @@ export { ToolAnnotationAssessor } from "./ToolAnnotationAssessor.js";
|
|
|
30
30
|
export { ProhibitedLibrariesAssessor } from "./ProhibitedLibrariesAssessor.js";
|
|
31
31
|
export { ManifestValidationAssessor } from "./ManifestValidationAssessor.js";
|
|
32
32
|
export { PortabilityAssessor } from "./PortabilityAssessor.js";
|
|
33
|
+
export { ExternalAPIScannerAssessor } from "./ExternalAPIScannerAssessor.js";
|
|
33
34
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -33,3 +33,4 @@ export { ToolAnnotationAssessor } from "./ToolAnnotationAssessor.js";
|
|
|
33
33
|
export { ProhibitedLibrariesAssessor } from "./ProhibitedLibrariesAssessor.js";
|
|
34
34
|
export { ManifestValidationAssessor } from "./ManifestValidationAssessor.js";
|
|
35
35
|
export { PortabilityAssessor } from "./PortabilityAssessor.js";
|
|
36
|
+
export { ExternalAPIScannerAssessor } from "./ExternalAPIScannerAssessor.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Client-side application for the Enhanced MCP Inspector with assessment capabilities",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bryan Thompson <bryan@triepod.ai>",
|