@bryan-thompson/inspector-assessment-client 1.15.1 → 1.16.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 (54) hide show
  1. package/dist/assets/{OAuthCallback-tZBHqkSF.js → OAuthCallback-CayYEvRg.js} +1 -1
  2. package/dist/assets/{OAuthDebugCallback-D73S8G8X.js → OAuthDebugCallback-CijTatbL.js} +1 -1
  3. package/dist/assets/{index-BAbFakRL.js → index-B9ESGk3E.js} +745 -4350
  4. package/dist/index.html +1 -1
  5. package/lib/lib/assessmentTypes.d.ts +129 -0
  6. package/lib/lib/assessmentTypes.d.ts.map +1 -1
  7. package/lib/lib/assessmentTypes.js +20 -0
  8. package/lib/lib/securityPatterns.d.ts +2 -2
  9. package/lib/lib/securityPatterns.d.ts.map +1 -1
  10. package/lib/lib/securityPatterns.js +290 -15
  11. package/lib/services/assessment/AssessmentOrchestrator.d.ts +67 -0
  12. package/lib/services/assessment/AssessmentOrchestrator.d.ts.map +1 -1
  13. package/lib/services/assessment/AssessmentOrchestrator.js +91 -1
  14. package/lib/services/assessment/ResponseValidator.d.ts +7 -34
  15. package/lib/services/assessment/ResponseValidator.d.ts.map +1 -1
  16. package/lib/services/assessment/ResponseValidator.js +100 -704
  17. package/lib/services/assessment/config/annotationPatterns.js +1 -1
  18. package/lib/services/assessment/lib/RequestHistoryAnalyzer.d.ts +67 -0
  19. package/lib/services/assessment/lib/RequestHistoryAnalyzer.d.ts.map +1 -0
  20. package/lib/services/assessment/lib/RequestHistoryAnalyzer.js +191 -0
  21. package/lib/services/assessment/lib/claudeCodeBridge.d.ts +1 -0
  22. package/lib/services/assessment/lib/claudeCodeBridge.d.ts.map +1 -1
  23. package/lib/services/assessment/lib/claudeCodeBridge.js +5 -4
  24. package/lib/services/assessment/modules/AuthenticationAssessor.d.ts +4 -0
  25. package/lib/services/assessment/modules/AuthenticationAssessor.d.ts.map +1 -1
  26. package/lib/services/assessment/modules/AuthenticationAssessor.js +97 -1
  27. package/lib/services/assessment/modules/CrossCapabilitySecurityAssessor.d.ts +39 -0
  28. package/lib/services/assessment/modules/CrossCapabilitySecurityAssessor.d.ts.map +1 -0
  29. package/lib/services/assessment/modules/CrossCapabilitySecurityAssessor.js +330 -0
  30. package/lib/services/assessment/modules/FunctionalityAssessor.d.ts.map +1 -1
  31. package/lib/services/assessment/modules/FunctionalityAssessor.js +46 -13
  32. package/lib/services/assessment/modules/MCPSpecComplianceAssessor.d.ts +5 -0
  33. package/lib/services/assessment/modules/MCPSpecComplianceAssessor.d.ts.map +1 -1
  34. package/lib/services/assessment/modules/MCPSpecComplianceAssessor.js +81 -0
  35. package/lib/services/assessment/modules/ManifestValidationAssessor.js +1 -1
  36. package/lib/services/assessment/modules/PromptAssessor.d.ts +30 -0
  37. package/lib/services/assessment/modules/PromptAssessor.d.ts.map +1 -0
  38. package/lib/services/assessment/modules/PromptAssessor.js +367 -0
  39. package/lib/services/assessment/modules/ResourceAssessor.d.ts +28 -0
  40. package/lib/services/assessment/modules/ResourceAssessor.d.ts.map +1 -0
  41. package/lib/services/assessment/modules/ResourceAssessor.js +296 -0
  42. package/lib/services/assessment/modules/SecurityAssessor.d.ts +4 -2
  43. package/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
  44. package/lib/services/assessment/modules/SecurityAssessor.js +10 -41
  45. package/lib/utils/jsonUtils.d.ts +68 -0
  46. package/lib/utils/jsonUtils.d.ts.map +1 -0
  47. package/lib/utils/jsonUtils.js +141 -0
  48. package/lib/utils/paramUtils.d.ts +11 -0
  49. package/lib/utils/paramUtils.d.ts.map +1 -0
  50. package/lib/utils/paramUtils.js +37 -0
  51. package/lib/utils/schemaUtils.d.ts +74 -0
  52. package/lib/utils/schemaUtils.d.ts.map +1 -0
  53. package/lib/utils/schemaUtils.js +268 -0
  54. package/package.json +1 -1
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Cleans parameters by removing undefined, null, and empty string values for optional fields
3
+ * while preserving all values for required fields and fields with explicit default values.
4
+ *
5
+ * @param params - The parameters object to clean
6
+ * @param schema - The JSON schema defining which fields are required
7
+ * @returns Cleaned parameters object with optional empty fields omitted
8
+ */
9
+ export function cleanParams(params, schema) {
10
+ const cleaned = {};
11
+ const required = schema.required || [];
12
+ const properties = schema.properties || {};
13
+ for (const [key, value] of Object.entries(params)) {
14
+ const isFieldRequired = required.includes(key);
15
+ const fieldSchema = properties[key];
16
+ // Check if the field has an explicit default value
17
+ const hasDefault = fieldSchema && "default" in fieldSchema;
18
+ const defaultValue = hasDefault ? fieldSchema.default : undefined;
19
+ if (isFieldRequired) {
20
+ // Required fields: always include, even if empty string or falsy
21
+ cleaned[key] = value;
22
+ }
23
+ else if (hasDefault && value === defaultValue) {
24
+ // Field has a default value and current value matches it - preserve it
25
+ // This is important for cases like default: null
26
+ cleaned[key] = value;
27
+ }
28
+ else {
29
+ // Optional fields: only include if they have meaningful values
30
+ if (value !== undefined && value !== "" && value !== null) {
31
+ cleaned[key] = value;
32
+ }
33
+ // Empty strings, undefined, null for optional fields → omit completely
34
+ }
35
+ }
36
+ return cleaned;
37
+ }
@@ -0,0 +1,74 @@
1
+ import type { JsonValue, JsonSchemaType } from "./jsonUtils.js";
2
+ import type { ValidateFunction } from "ajv";
3
+ import type { Tool, JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
4
+ /**
5
+ * Compiles and caches output schema validators for a list of tools
6
+ * Following the same pattern as SDK's Client.cacheToolOutputSchemas
7
+ * @param tools Array of tools that may have output schemas
8
+ */
9
+ export declare function cacheToolOutputSchemas(tools: Tool[]): void;
10
+ /**
11
+ * Gets the cached output schema validator for a tool
12
+ * Following the same pattern as SDK's Client.getToolOutputValidator
13
+ * @param toolName Name of the tool
14
+ * @returns The compiled validator function, or undefined if not found
15
+ */
16
+ export declare function getToolOutputValidator(toolName: string): ValidateFunction | undefined;
17
+ /**
18
+ * Validates structured content against a tool's output schema
19
+ * Returns validation result with detailed error messages
20
+ * @param toolName Name of the tool
21
+ * @param structuredContent The structured content to validate
22
+ * @returns An object with isValid boolean and optional error message
23
+ */
24
+ export declare function validateToolOutput(toolName: string, structuredContent: unknown): {
25
+ isValid: boolean;
26
+ error?: string;
27
+ };
28
+ /**
29
+ * Checks if a tool has an output schema
30
+ * @param toolName Name of the tool
31
+ * @returns true if the tool has an output schema
32
+ */
33
+ export declare function hasOutputSchema(toolName: string): boolean;
34
+ /**
35
+ * Generates a default value based on a JSON schema type
36
+ * @param schema The JSON schema definition
37
+ * @param propertyName Optional property name for checking if it's required in parent schema
38
+ * @param parentSchema Optional parent schema to check required array
39
+ * @returns A default value matching the schema type
40
+ */
41
+ export declare function generateDefaultValue(schema: JsonSchemaType, propertyName?: string, parentSchema?: JsonSchemaType): JsonValue;
42
+ /**
43
+ * Helper function to check if a property is required in a schema
44
+ * @param propertyName The name of the property to check
45
+ * @param schema The parent schema containing the required array
46
+ * @returns true if the property is required, false otherwise
47
+ */
48
+ export declare function isPropertyRequired(propertyName: string, schema: JsonSchemaType): boolean;
49
+ /**
50
+ * Resolves $ref references in JSON schema
51
+ * @param schema The schema that may contain $ref
52
+ * @param rootSchema The root schema to resolve references against
53
+ * @returns The resolved schema without $ref
54
+ */
55
+ export declare function resolveRef(schema: JsonSchemaType, rootSchema: JsonSchemaType): JsonSchemaType;
56
+ /**
57
+ * Normalizes union types (like string|null from FastMCP) to simple types for form rendering
58
+ * @param schema The JSON schema to normalize
59
+ * @returns A normalized schema or the original schema
60
+ */
61
+ export declare function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType;
62
+ /**
63
+ * Formats a field key into a human-readable label
64
+ * @param key The field key to format
65
+ * @returns A formatted label string
66
+ */
67
+ export declare function formatFieldLabel(key: string): string;
68
+ /**
69
+ * Resolves `$ref` references in a JSON-RPC "elicitation/create" message's `requestedSchema` field
70
+ * @param message The JSON-RPC message that may contain $ref references
71
+ * @returns A new message with resolved $ref references, or the original message if no resolution is needed
72
+ */
73
+ export declare function resolveRefsInMessage(message: JSONRPCMessage): JSONRPCMessage;
74
+ //# sourceMappingURL=schemaUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaUtils.d.ts","sourceRoot":"","sources":["../../src/utils/schemaUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAc,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAQ/E;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAe1D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,GACf,gBAAgB,GAAG,SAAS,CAE9B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,OAAO,GACzB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAetC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,cAAc,GAC5B,SAAS,CAkDX;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAET;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,cAAc,GACzB,cAAc,CAiChB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CA4FzE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CA+B5E"}
@@ -0,0 +1,268 @@
1
+ import Ajv from "ajv";
2
+ import { isJSONRPCRequest } from "@modelcontextprotocol/sdk/types.js";
3
+ const ajv = new Ajv();
4
+ // Cache for compiled validators
5
+ const toolOutputValidators = new Map();
6
+ /**
7
+ * Compiles and caches output schema validators for a list of tools
8
+ * Following the same pattern as SDK's Client.cacheToolOutputSchemas
9
+ * @param tools Array of tools that may have output schemas
10
+ */
11
+ export function cacheToolOutputSchemas(tools) {
12
+ toolOutputValidators.clear();
13
+ for (const tool of tools) {
14
+ if (tool.outputSchema) {
15
+ try {
16
+ const validator = ajv.compile(tool.outputSchema);
17
+ toolOutputValidators.set(tool.name, validator);
18
+ }
19
+ catch (error) {
20
+ console.warn(`Failed to compile output schema for tool ${tool.name}:`, error);
21
+ }
22
+ }
23
+ }
24
+ }
25
+ /**
26
+ * Gets the cached output schema validator for a tool
27
+ * Following the same pattern as SDK's Client.getToolOutputValidator
28
+ * @param toolName Name of the tool
29
+ * @returns The compiled validator function, or undefined if not found
30
+ */
31
+ export function getToolOutputValidator(toolName) {
32
+ return toolOutputValidators.get(toolName);
33
+ }
34
+ /**
35
+ * Validates structured content against a tool's output schema
36
+ * Returns validation result with detailed error messages
37
+ * @param toolName Name of the tool
38
+ * @param structuredContent The structured content to validate
39
+ * @returns An object with isValid boolean and optional error message
40
+ */
41
+ export function validateToolOutput(toolName, structuredContent) {
42
+ const validator = getToolOutputValidator(toolName);
43
+ if (!validator) {
44
+ return { isValid: true }; // No validator means no schema to validate against
45
+ }
46
+ const isValid = validator(structuredContent);
47
+ if (!isValid) {
48
+ return {
49
+ isValid: false,
50
+ error: ajv.errorsText(validator.errors),
51
+ };
52
+ }
53
+ return { isValid: true };
54
+ }
55
+ /**
56
+ * Checks if a tool has an output schema
57
+ * @param toolName Name of the tool
58
+ * @returns true if the tool has an output schema
59
+ */
60
+ export function hasOutputSchema(toolName) {
61
+ return toolOutputValidators.has(toolName);
62
+ }
63
+ /**
64
+ * Generates a default value based on a JSON schema type
65
+ * @param schema The JSON schema definition
66
+ * @param propertyName Optional property name for checking if it's required in parent schema
67
+ * @param parentSchema Optional parent schema to check required array
68
+ * @returns A default value matching the schema type
69
+ */
70
+ export function generateDefaultValue(schema, propertyName, parentSchema) {
71
+ if ("default" in schema && schema.default !== undefined) {
72
+ return schema.default;
73
+ }
74
+ // Check if this property is required in the parent schema
75
+ const isRequired = propertyName && parentSchema
76
+ ? isPropertyRequired(propertyName, parentSchema)
77
+ : false;
78
+ const isRootSchema = propertyName === undefined && parentSchema === undefined;
79
+ switch (schema.type) {
80
+ case "string":
81
+ return isRequired ? "" : undefined;
82
+ case "number":
83
+ case "integer":
84
+ return isRequired ? 0 : undefined;
85
+ case "boolean":
86
+ return isRequired ? false : undefined;
87
+ case "array":
88
+ return isRequired ? [] : undefined;
89
+ case "object": {
90
+ if (!schema.properties) {
91
+ return isRequired || isRootSchema ? {} : undefined;
92
+ }
93
+ const obj = {};
94
+ // Include required properties OR optional properties that declare a default
95
+ Object.entries(schema.properties).forEach(([key, prop]) => {
96
+ const hasExplicitDefault = "default" in prop && prop.default !== undefined;
97
+ if (isPropertyRequired(key, schema) || hasExplicitDefault) {
98
+ const value = generateDefaultValue(prop, key, schema);
99
+ if (value !== undefined) {
100
+ obj[key] = value;
101
+ }
102
+ }
103
+ });
104
+ if (Object.keys(obj).length === 0) {
105
+ return isRequired || isRootSchema ? {} : undefined;
106
+ }
107
+ return obj;
108
+ }
109
+ case "null":
110
+ return null;
111
+ default:
112
+ return undefined;
113
+ }
114
+ }
115
+ /**
116
+ * Helper function to check if a property is required in a schema
117
+ * @param propertyName The name of the property to check
118
+ * @param schema The parent schema containing the required array
119
+ * @returns true if the property is required, false otherwise
120
+ */
121
+ export function isPropertyRequired(propertyName, schema) {
122
+ return schema.required?.includes(propertyName) ?? false;
123
+ }
124
+ /**
125
+ * Resolves $ref references in JSON schema
126
+ * @param schema The schema that may contain $ref
127
+ * @param rootSchema The root schema to resolve references against
128
+ * @returns The resolved schema without $ref
129
+ */
130
+ export function resolveRef(schema, rootSchema) {
131
+ if (!("$ref" in schema) || !schema.$ref) {
132
+ return schema;
133
+ }
134
+ const ref = schema.$ref;
135
+ // Handle simple #/properties/name references
136
+ if (ref.startsWith("#/")) {
137
+ const path = ref.substring(2).split("/");
138
+ let current = rootSchema;
139
+ for (const segment of path) {
140
+ if (current &&
141
+ typeof current === "object" &&
142
+ current !== null &&
143
+ segment in current) {
144
+ current = current[segment];
145
+ }
146
+ else {
147
+ // If reference cannot be resolved, return the original schema
148
+ console.warn(`Could not resolve $ref: ${ref}`);
149
+ return schema;
150
+ }
151
+ }
152
+ return current;
153
+ }
154
+ // For other types of references, return the original schema
155
+ console.warn(`Unsupported $ref format: ${ref}`);
156
+ return schema;
157
+ }
158
+ /**
159
+ * Normalizes union types (like string|null from FastMCP) to simple types for form rendering
160
+ * @param schema The JSON schema to normalize
161
+ * @returns A normalized schema or the original schema
162
+ */
163
+ export function normalizeUnionType(schema) {
164
+ // Handle anyOf with exactly string and null (FastMCP pattern)
165
+ if (schema.anyOf &&
166
+ schema.anyOf.length === 2 &&
167
+ schema.anyOf.some((t) => t.type === "string") &&
168
+ schema.anyOf.some((t) => t.type === "null")) {
169
+ return { ...schema, type: "string", anyOf: undefined, nullable: true };
170
+ }
171
+ // Handle anyOf with exactly boolean and null (FastMCP pattern)
172
+ if (schema.anyOf &&
173
+ schema.anyOf.length === 2 &&
174
+ schema.anyOf.some((t) => t.type === "boolean") &&
175
+ schema.anyOf.some((t) => t.type === "null")) {
176
+ return { ...schema, type: "boolean", anyOf: undefined, nullable: true };
177
+ }
178
+ // Handle anyOf with exactly number and null (FastMCP pattern)
179
+ if (schema.anyOf &&
180
+ schema.anyOf.length === 2 &&
181
+ schema.anyOf.some((t) => t.type === "number") &&
182
+ schema.anyOf.some((t) => t.type === "null")) {
183
+ return { ...schema, type: "number", anyOf: undefined, nullable: true };
184
+ }
185
+ // Handle anyOf with exactly integer and null (FastMCP pattern)
186
+ if (schema.anyOf &&
187
+ schema.anyOf.length === 2 &&
188
+ schema.anyOf.some((t) => t.type === "integer") &&
189
+ schema.anyOf.some((t) => t.type === "null")) {
190
+ return { ...schema, type: "integer", anyOf: undefined, nullable: true };
191
+ }
192
+ // Handle anyOf with exactly array and null (FastMCP pattern)
193
+ if (schema.anyOf &&
194
+ schema.anyOf.length === 2 &&
195
+ schema.anyOf.some((t) => t.type === "array") &&
196
+ schema.anyOf.some((t) => t.type === "null")) {
197
+ return { ...schema, type: "array", anyOf: undefined, nullable: true };
198
+ }
199
+ // Handle array type with exactly string and null
200
+ if (Array.isArray(schema.type) &&
201
+ schema.type.length === 2 &&
202
+ schema.type.includes("string") &&
203
+ schema.type.includes("null")) {
204
+ return { ...schema, type: "string", nullable: true };
205
+ }
206
+ // Handle array type with exactly boolean and null
207
+ if (Array.isArray(schema.type) &&
208
+ schema.type.length === 2 &&
209
+ schema.type.includes("boolean") &&
210
+ schema.type.includes("null")) {
211
+ return { ...schema, type: "boolean", nullable: true };
212
+ }
213
+ // Handle array type with exactly number and null
214
+ if (Array.isArray(schema.type) &&
215
+ schema.type.length === 2 &&
216
+ schema.type.includes("number") &&
217
+ schema.type.includes("null")) {
218
+ return { ...schema, type: "number", nullable: true };
219
+ }
220
+ // Handle array type with exactly integer and null
221
+ if (Array.isArray(schema.type) &&
222
+ schema.type.length === 2 &&
223
+ schema.type.includes("integer") &&
224
+ schema.type.includes("null")) {
225
+ return { ...schema, type: "integer", nullable: true };
226
+ }
227
+ return schema;
228
+ }
229
+ /**
230
+ * Formats a field key into a human-readable label
231
+ * @param key The field key to format
232
+ * @returns A formatted label string
233
+ */
234
+ export function formatFieldLabel(key) {
235
+ return key
236
+ .replace(/([A-Z])/g, " $1") // Insert space before capital letters
237
+ .replace(/_/g, " ") // Replace underscores with spaces
238
+ .replace(/^\w/, (c) => c.toUpperCase()); // Capitalize first letter
239
+ }
240
+ /**
241
+ * Resolves `$ref` references in a JSON-RPC "elicitation/create" message's `requestedSchema` field
242
+ * @param message The JSON-RPC message that may contain $ref references
243
+ * @returns A new message with resolved $ref references, or the original message if no resolution is needed
244
+ */
245
+ export function resolveRefsInMessage(message) {
246
+ if (!isJSONRPCRequest(message) || !message.params?.requestedSchema) {
247
+ return message;
248
+ }
249
+ const requestedSchema = message.params.requestedSchema;
250
+ if (!requestedSchema?.properties) {
251
+ return message;
252
+ }
253
+ const resolvedMessage = {
254
+ ...message,
255
+ params: {
256
+ ...message.params,
257
+ requestedSchema: {
258
+ ...requestedSchema,
259
+ properties: Object.fromEntries(Object.entries(requestedSchema.properties).map(([key, propSchema]) => {
260
+ const resolved = resolveRef(propSchema, requestedSchema);
261
+ const normalized = normalizeUnionType(resolved);
262
+ return [key, normalized];
263
+ })),
264
+ },
265
+ },
266
+ };
267
+ return resolvedMessage;
268
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bryan-thompson/inspector-assessment-client",
3
- "version": "1.15.1",
3
+ "version": "1.16.1",
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>",