@bryan-thompson/inspector-assessment-client 1.6.0 → 1.7.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.
Files changed (74) hide show
  1. package/dist/assets/{OAuthCallback-ZcXdfhZQ.js → OAuthCallback-Xo9zS7pv.js} +1 -1
  2. package/dist/assets/{OAuthDebugCallback-xt1SlIHS.js → OAuthDebugCallback-CaIey8K_.js} +1 -1
  3. package/dist/assets/{index-B3lTiDVe.js → index-nCPw6E-c.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,253 @@
1
+ /**
2
+ * Functionality Assessor Module
3
+ * Tests tool functionality and basic operations
4
+ */
5
+ import { BaseAssessor } from "./BaseAssessor.js";
6
+ import { ResponseValidator } from "../ResponseValidator.js";
7
+ export class FunctionalityAssessor extends BaseAssessor {
8
+ /**
9
+ * Select tools for testing based on configuration
10
+ */
11
+ selectToolsForTesting(tools) {
12
+ // Prefer new selectedToolsForTesting configuration
13
+ // Note: undefined/null means "test all" (default), empty array [] means "test none" (explicit)
14
+ if (this.config.selectedToolsForTesting !== undefined) {
15
+ const selectedNames = new Set(this.config.selectedToolsForTesting);
16
+ const selectedTools = tools.filter((tool) => selectedNames.has(tool.name));
17
+ // Empty array means user explicitly selected 0 tools
18
+ if (this.config.selectedToolsForTesting.length === 0) {
19
+ this.log(`User selected 0 tools for functionality testing - skipping tests`);
20
+ return [];
21
+ }
22
+ // If no tools matched the names (config out of sync), log warning but respect selection
23
+ if (selectedTools.length === 0) {
24
+ this.log(`Warning: No tools matched selection (${this.config.selectedToolsForTesting.join(", ")})`);
25
+ return [];
26
+ }
27
+ this.log(`Testing ${selectedTools.length} selected tools out of ${tools.length} for functionality`);
28
+ return selectedTools;
29
+ }
30
+ // Default: test all tools
31
+ this.log(`Testing all ${tools.length} tools for functionality`);
32
+ return tools;
33
+ }
34
+ async assess(context) {
35
+ this.log(`Starting functionality assessment${this.config.reviewerMode ? " (reviewer mode - quick verification)" : ""}`);
36
+ const toolResults = [];
37
+ const brokenTools = [];
38
+ let workingTools = 0;
39
+ // Select tools for testing
40
+ const toolsToTest = this.selectToolsForTesting(context.tools);
41
+ for (const tool of toolsToTest) {
42
+ this.testCount++;
43
+ const result = await this.testTool(tool, context.callTool);
44
+ toolResults.push(result);
45
+ // Add delay between tests to avoid rate limiting
46
+ if (this.config.delayBetweenTests && this.config.delayBetweenTests > 0) {
47
+ await this.sleep(this.config.delayBetweenTests);
48
+ }
49
+ if (result.status === "working") {
50
+ workingTools++;
51
+ }
52
+ else if (result.status === "broken") {
53
+ brokenTools.push(tool.name);
54
+ if (this.config.skipBrokenTools) {
55
+ this.log(`Skipping further tests for broken tool: ${tool.name}`);
56
+ }
57
+ }
58
+ }
59
+ const totalTools = toolsToTest.length;
60
+ const testedTools = toolResults.filter((r) => r.tested).length;
61
+ const coveragePercentage = testedTools > 0 ? (workingTools / testedTools) * 100 : 0;
62
+ const status = this.determineStatus(workingTools, testedTools);
63
+ const explanation = this.generateExplanation(totalTools, testedTools, workingTools, brokenTools);
64
+ return {
65
+ totalTools,
66
+ testedTools,
67
+ workingTools,
68
+ brokenTools,
69
+ coveragePercentage,
70
+ status,
71
+ explanation,
72
+ toolResults,
73
+ };
74
+ }
75
+ async testTool(tool, callTool) {
76
+ const startTime = Date.now();
77
+ try {
78
+ // Generate minimal valid parameters
79
+ const testParams = this.generateMinimalParams(tool);
80
+ this.log(`Testing tool: ${tool.name} with params: ${JSON.stringify(testParams)}`);
81
+ // Execute tool with timeout
82
+ const response = await this.executeWithTimeout(callTool(tool.name, testParams), this.config.testTimeout);
83
+ const executionTime = Date.now() - startTime;
84
+ // Check if response indicates an error using base class method
85
+ // Use strict mode for functionality testing - only check explicit error indicators
86
+ // This prevents false positives where valid responses mention "error" in their content
87
+ if (this.isErrorResponse(response, true)) {
88
+ // Check if this is a business logic error (validation error)
89
+ // Tools that correctly validate inputs should be marked as "working"
90
+ const validationContext = {
91
+ tool,
92
+ input: testParams,
93
+ response,
94
+ };
95
+ if (ResponseValidator.isBusinessLogicError(validationContext)) {
96
+ // Tool is correctly validating inputs - this is expected behavior
97
+ return {
98
+ toolName: tool.name,
99
+ tested: true,
100
+ status: "working",
101
+ executionTime,
102
+ testParameters: testParams,
103
+ response,
104
+ };
105
+ }
106
+ // Real tool failure (not just validation)
107
+ return {
108
+ toolName: tool.name,
109
+ tested: true,
110
+ status: "broken",
111
+ error: this.extractErrorMessage(response),
112
+ executionTime,
113
+ testParameters: testParams,
114
+ response,
115
+ };
116
+ }
117
+ return {
118
+ toolName: tool.name,
119
+ tested: true,
120
+ status: "working",
121
+ executionTime,
122
+ testParameters: testParams,
123
+ response,
124
+ };
125
+ }
126
+ catch (error) {
127
+ return {
128
+ toolName: tool.name,
129
+ tested: true,
130
+ status: "broken",
131
+ error: this.extractErrorMessage(error),
132
+ executionTime: Date.now() - startTime,
133
+ };
134
+ }
135
+ }
136
+ generateMinimalParams(tool) {
137
+ if (!tool.inputSchema)
138
+ return {};
139
+ const schema = typeof tool.inputSchema === "string"
140
+ ? this.safeJsonParse(tool.inputSchema)
141
+ : tool.inputSchema;
142
+ if (!schema?.properties)
143
+ return {};
144
+ const params = {};
145
+ const required = schema.required || [];
146
+ // For functionality testing, only generate REQUIRED parameters
147
+ // This avoids triggering validation errors on optional parameters with complex rules
148
+ for (const [key, prop] of Object.entries(schema.properties)) {
149
+ // Only include required parameters for basic functionality testing
150
+ if (required.includes(key)) {
151
+ params[key] = this.generateParamValue(prop, key);
152
+ }
153
+ }
154
+ return params;
155
+ }
156
+ generateParamValue(prop, fieldName, includeOptional = false) {
157
+ const type = prop.type;
158
+ // Check for UUID format requirements
159
+ const lowerFieldName = fieldName?.toLowerCase() || "";
160
+ const requiresUuid = lowerFieldName.includes("uuid") ||
161
+ lowerFieldName.includes("page_id") ||
162
+ lowerFieldName.includes("database_id") ||
163
+ lowerFieldName.includes("user_id") ||
164
+ lowerFieldName.includes("block_id") ||
165
+ lowerFieldName.includes("comment_id") ||
166
+ lowerFieldName.includes("workspace_id") ||
167
+ (prop.description &&
168
+ (prop.description.toLowerCase().includes("uuid") ||
169
+ prop.description.toLowerCase().includes("universally unique")));
170
+ switch (type) {
171
+ case "string":
172
+ if (prop.enum)
173
+ return prop.enum[0];
174
+ if (prop.format === "uri")
175
+ return "https://example.com";
176
+ if (prop.format === "email")
177
+ return "test@example.com";
178
+ // Return valid UUID for UUID-required fields
179
+ if (requiresUuid)
180
+ return "550e8400-e29b-41d4-a716-446655440000";
181
+ return "test";
182
+ case "number":
183
+ case "integer":
184
+ if (prop.minimum !== undefined)
185
+ return prop.minimum;
186
+ if (prop.maximum !== undefined)
187
+ return Math.min(prop.maximum, 10);
188
+ // Use 10 instead of 0 for better validity (page_size, limit, etc.)
189
+ return 10;
190
+ case "boolean":
191
+ return false;
192
+ case "array":
193
+ // Generate array with sample items based on items schema
194
+ if (prop.items) {
195
+ return [
196
+ this.generateParamValue(prop.items, undefined, includeOptional),
197
+ ];
198
+ }
199
+ return [];
200
+ case "object":
201
+ // Generate object with properties based on schema
202
+ if (prop.properties) {
203
+ const obj = {};
204
+ const requiredProps = prop.required || [];
205
+ // Generate properties based on includeOptional flag
206
+ // includeOptional=false: Only required properties (for functionality testing)
207
+ // includeOptional=true: All properties (for test input generation)
208
+ for (const [key, subProp] of Object.entries(prop.properties)) {
209
+ if (includeOptional || requiredProps.includes(key)) {
210
+ obj[key] = this.generateParamValue(subProp, key, includeOptional);
211
+ }
212
+ }
213
+ return obj;
214
+ }
215
+ return {};
216
+ default:
217
+ // Handle union types (anyOf, oneOf) by trying the first option
218
+ if (prop.anyOf && Array.isArray(prop.anyOf) && prop.anyOf.length > 0) {
219
+ return this.generateParamValue(prop.anyOf[0], fieldName, includeOptional);
220
+ }
221
+ if (prop.oneOf && Array.isArray(prop.oneOf) && prop.oneOf.length > 0) {
222
+ return this.generateParamValue(prop.oneOf[0], fieldName, includeOptional);
223
+ }
224
+ // Return empty object instead of null to avoid validation errors
225
+ return {};
226
+ }
227
+ }
228
+ // Public method for testing purposes - allows tests to verify parameter generation logic
229
+ // Always includes optional properties to test full schema
230
+ generateTestInput(schema) {
231
+ return this.generateParamValue(schema, undefined, true);
232
+ }
233
+ generateExplanation(total, tested, working, broken) {
234
+ const parts = [];
235
+ if (total === 0) {
236
+ return "No tools selected for functionality testing. Select tools to run functionality assessments.";
237
+ }
238
+ parts.push(`Tested ${tested} out of ${total} tools.`);
239
+ if (tested > 0) {
240
+ const successRate = (working / tested) * 100;
241
+ parts.push(`${working} tools working correctly (${successRate.toFixed(1)}% success rate).`);
242
+ }
243
+ if (broken.length > 0) {
244
+ if (broken.length <= 3) {
245
+ parts.push(`Broken tools: ${broken.join(", ")}.`);
246
+ }
247
+ else {
248
+ parts.push(`${broken.length} tools failed testing.`);
249
+ }
250
+ }
251
+ return parts.join(" ");
252
+ }
253
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * MCP Spec Compliance Assessment Module
3
+ * Simple, focused MCP protocol validation for directory approval
4
+ */
5
+ import { MCPSpecComplianceAssessment, AssessmentConfiguration } from "../../../lib/assessmentTypes.js";
6
+ import { BaseAssessor } from "./BaseAssessor.js";
7
+ import { AssessmentContext } from "../AssessmentOrchestrator.js";
8
+ export declare class MCPSpecComplianceAssessor extends BaseAssessor {
9
+ private ajv;
10
+ constructor(config: AssessmentConfiguration);
11
+ /**
12
+ * Assess MCP Specification Compliance - Hybrid Approach
13
+ * Separates protocol-verified checks from metadata-based hints
14
+ */
15
+ assess(context: AssessmentContext): Promise<MCPSpecComplianceAssessment>;
16
+ /**
17
+ * Extract protocol version from context
18
+ */
19
+ private extractProtocolVersion;
20
+ /**
21
+ * Check JSON-RPC 2.0 compliance
22
+ */
23
+ private checkJsonRpcCompliance;
24
+ /**
25
+ * Check if server info is valid and properly formatted
26
+ */
27
+ private checkServerInfoValidity;
28
+ /**
29
+ * Check schema compliance for all tools
30
+ */
31
+ private checkSchemaCompliance;
32
+ /**
33
+ * Check error response compliance
34
+ */
35
+ private checkErrorResponses;
36
+ /**
37
+ * Check if tools have structured output support (2025-06-18 feature)
38
+ */
39
+ private checkStructuredOutputSupport;
40
+ /**
41
+ * Assess transport compliance (basic check)
42
+ */
43
+ private assessTransportCompliance;
44
+ /**
45
+ * Assess annotation support
46
+ */
47
+ private assessAnnotationSupport;
48
+ /**
49
+ * Assess streaming support
50
+ */
51
+ private assessStreamingSupport;
52
+ /**
53
+ * Assess OAuth implementation (optional)
54
+ */
55
+ private assessOAuthCompliance;
56
+ /**
57
+ * Extract metadata hints from server context
58
+ * LOW CONFIDENCE - these are just parsed from metadata, not tested
59
+ */
60
+ private extractMetadataHints;
61
+ /**
62
+ * Generate explanation based on protocol checks
63
+ */
64
+ private generateExplanationHybrid;
65
+ /**
66
+ * Generate simplified recommendations based on protocol checks and metadata hints
67
+ */
68
+ private generateRecommendationsHybrid;
69
+ }
70
+ //# sourceMappingURL=MCPSpecComplianceAssessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MCPSpecComplianceAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/MCPSpecComplianceAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,2BAA2B,EAM3B,uBAAuB,EAGxB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,yBAA0B,SAAQ,YAAY;IACzD,OAAO,CAAC,GAAG,CAAc;gBAEb,MAAM,EAAE,uBAAuB;IAK3C;;;OAGG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,2BAA2B,CAAC;IAqGvC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAwB9B;;OAEG;YACW,sBAAsB;IAkBpC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAyB/B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyC7B;;OAEG;YACW,mBAAmB;IAwBjC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAiBpC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAyFjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAsB/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4B9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA2C7B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAoF5B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAyBjC;;OAEG;IACH,OAAO,CAAC,6BAA6B;CA0DtC"}