@bryan-thompson/inspector-assessment-client 1.13.1 → 1.14.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.
@@ -1,4 +1,4 @@
1
- import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-DtKbQaUh.js";
1
+ import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-BAJG90Yd.js";
2
2
  const OAuthCallback = ({ onConnect }) => {
3
3
  const { toast } = useToast();
4
4
  const hasProcessedRef = reactExports.useRef(false);
@@ -1,4 +1,4 @@
1
- import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-DtKbQaUh.js";
1
+ import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-BAJG90Yd.js";
2
2
  const OAuthDebugCallback = ({ onConnect }) => {
3
3
  reactExports.useEffect(() => {
4
4
  let isProcessed = false;
@@ -16320,7 +16320,7 @@ object({
16320
16320
  token_type_hint: string().optional()
16321
16321
  }).strip();
16322
16322
  const name = "@bryan-thompson/inspector-assessment-client";
16323
- const version$1 = "1.13.1";
16323
+ const version$1 = "1.14.0";
16324
16324
  const packageJson = {
16325
16325
  name,
16326
16326
  version: version$1
@@ -48863,7 +48863,7 @@ const useTheme = () => {
48863
48863
  [theme, setThemeWithSideEffect]
48864
48864
  );
48865
48865
  };
48866
- const version = "1.13.1";
48866
+ const version = "1.14.0";
48867
48867
  var [createTooltipContext] = createContextScope("Tooltip", [
48868
48868
  createPopperScope
48869
48869
  ]);
@@ -51556,7 +51556,8 @@ const DEFAULT_ASSESSMENT_CONFIG = {
51556
51556
  prohibitedLibraries: false,
51557
51557
  manifestValidation: false,
51558
51558
  portability: false,
51559
- externalAPIScanner: false
51559
+ externalAPIScanner: false,
51560
+ authentication: false
51560
51561
  }
51561
51562
  };
51562
51563
  const REVIEWER_MODE_CONFIG = {
@@ -51596,7 +51597,8 @@ const REVIEWER_MODE_CONFIG = {
51596
51597
  prohibitedLibraries: false,
51597
51598
  manifestValidation: false,
51598
51599
  portability: false,
51599
- externalAPIScanner: false
51600
+ externalAPIScanner: false,
51601
+ authentication: false
51600
51602
  }
51601
51603
  };
51602
51604
  const DEVELOPER_MODE_CONFIG = {
@@ -51633,7 +51635,8 @@ const DEVELOPER_MODE_CONFIG = {
51633
51635
  prohibitedLibraries: true,
51634
51636
  manifestValidation: true,
51635
51637
  portability: true,
51636
- externalAPIScanner: true
51638
+ externalAPIScanner: true,
51639
+ authentication: true
51637
51640
  }
51638
51641
  };
51639
51642
  class BaseAssessor {
@@ -54777,6 +54780,11 @@ class FunctionalityAssessor extends BaseAssessor {
54777
54780
  workingTools,
54778
54781
  brokenTools
54779
54782
  );
54783
+ const tools = context.tools.map((t) => ({
54784
+ name: t.name,
54785
+ description: t.description,
54786
+ inputSchema: t.inputSchema
54787
+ }));
54780
54788
  return {
54781
54789
  totalTools,
54782
54790
  testedTools,
@@ -54785,7 +54793,8 @@ class FunctionalityAssessor extends BaseAssessor {
54785
54793
  coveragePercentage,
54786
54794
  status,
54787
54795
  explanation,
54788
- toolResults
54796
+ toolResults,
54797
+ tools
54789
54798
  };
54790
54799
  }
54791
54800
  async testTool(tool, callTool) {
@@ -61868,13 +61877,13 @@ const App = () => {
61868
61877
  ) });
61869
61878
  if (window.location.pathname === "/oauth/callback") {
61870
61879
  const OAuthCallback = React.lazy(
61871
- () => __vitePreload(() => import("./OAuthCallback-Dg3beipA.js"), true ? [] : void 0)
61880
+ () => __vitePreload(() => import("./OAuthCallback-DaKwjxdn.js"), true ? [] : void 0)
61872
61881
  );
61873
61882
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
61874
61883
  }
61875
61884
  if (window.location.pathname === "/oauth/callback/debug") {
61876
61885
  const OAuthDebugCallback = React.lazy(
61877
- () => __vitePreload(() => import("./OAuthDebugCallback-zRUPyR0T.js"), true ? [] : void 0)
61886
+ () => __vitePreload(() => import("./OAuthDebugCallback-HiI2IPgB.js"), true ? [] : void 0)
61878
61887
  );
61879
61888
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
61880
61889
  }
@@ -1841,6 +1841,9 @@ video {
1841
1841
  .lowercase {
1842
1842
  text-transform: lowercase;
1843
1843
  }
1844
+ .capitalize {
1845
+ text-transform: capitalize;
1846
+ }
1844
1847
  .italic {
1845
1848
  font-style: italic;
1846
1849
  }
package/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/mcp.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>MCP Inspector</title>
8
- <script type="module" crossorigin src="/assets/index-DtKbQaUh.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-Cuc9GxjD.css">
8
+ <script type="module" crossorigin src="/assets/index-BAJG90Yd.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-BdXNC65t.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root" class="w-full"></div>
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Assessment Differ
3
+ * Compares two assessment runs to detect regressions or improvements.
4
+ *
5
+ * Use Cases:
6
+ * - Compare bundle v1.0 vs v1.1
7
+ * - Track assessment changes over time
8
+ * - CI/CD regression detection
9
+ */
10
+ import type { MCPDirectoryAssessment, AssessmentStatus } from "./assessmentTypes.js";
11
+ /**
12
+ * Change direction for a metric
13
+ */
14
+ export type ChangeDirection = "improved" | "regressed" | "unchanged";
15
+ /**
16
+ * Detailed change information for a single module
17
+ */
18
+ export interface ModuleChange {
19
+ module: string;
20
+ baselineStatus: AssessmentStatus;
21
+ currentStatus: AssessmentStatus;
22
+ baselineScore?: number;
23
+ currentScore?: number;
24
+ change: ChangeDirection;
25
+ details: string;
26
+ }
27
+ /**
28
+ * Security-specific delta tracking
29
+ */
30
+ export interface SecurityDelta {
31
+ newVulnerabilities: string[];
32
+ fixedVulnerabilities: string[];
33
+ netChange: number;
34
+ baselineCount: number;
35
+ currentCount: number;
36
+ }
37
+ /**
38
+ * Functionality-specific delta tracking
39
+ */
40
+ export interface FunctionalityDelta {
41
+ newBrokenTools: string[];
42
+ fixedTools: string[];
43
+ netChange: number;
44
+ baselineWorking: number;
45
+ currentWorking: number;
46
+ }
47
+ /**
48
+ * Full assessment comparison result
49
+ */
50
+ export interface AssessmentDiff {
51
+ serverName: string;
52
+ baseline: {
53
+ version?: string;
54
+ date: string;
55
+ assessorVersion: string;
56
+ };
57
+ current: {
58
+ version?: string;
59
+ date: string;
60
+ assessorVersion: string;
61
+ };
62
+ summary: {
63
+ overallChange: ChangeDirection;
64
+ baselineStatus: AssessmentStatus;
65
+ currentStatus: AssessmentStatus;
66
+ modulesImproved: number;
67
+ modulesRegressed: number;
68
+ modulesUnchanged: number;
69
+ };
70
+ moduleChanges: ModuleChange[];
71
+ securityDelta: SecurityDelta;
72
+ functionalityDelta: FunctionalityDelta;
73
+ recommendations: string[];
74
+ }
75
+ /**
76
+ * Compare two assessment runs
77
+ */
78
+ export declare function compareAssessments(baseline: MCPDirectoryAssessment, current: MCPDirectoryAssessment): AssessmentDiff;
79
+ //# sourceMappingURL=assessmentDiffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assessmentDiffer.d.ts","sourceRoot":"","sources":["../../src/lib/assessmentDiffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,gBAAgB,CAAC;IACjC,aAAa,EAAE,gBAAgB,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,OAAO,EAAE;QACP,aAAa,EAAE,eAAe,CAAC;QAC/B,cAAc,EAAE,gBAAgB,CAAC;QACjC,aAAa,EAAE,gBAAgB,CAAC;QAChC,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,sBAAsB,GAC9B,cAAc,CA4DhB"}
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Assessment Differ
3
+ * Compares two assessment runs to detect regressions or improvements.
4
+ *
5
+ * Use Cases:
6
+ * - Compare bundle v1.0 vs v1.1
7
+ * - Track assessment changes over time
8
+ * - CI/CD regression detection
9
+ */
10
+ /**
11
+ * Compare two assessment runs
12
+ */
13
+ export function compareAssessments(baseline, current) {
14
+ const moduleChanges = compareModules(baseline, current);
15
+ const securityDelta = compareSecurityResults(baseline, current);
16
+ const functionalityDelta = compareFunctionalityResults(baseline, current);
17
+ const improved = moduleChanges.filter((m) => m.change === "improved").length;
18
+ const regressed = moduleChanges.filter((m) => m.change === "regressed").length;
19
+ const unchanged = moduleChanges.filter((m) => m.change === "unchanged").length;
20
+ // Determine overall change
21
+ let overallChange = "unchanged";
22
+ if (regressed > 0 ||
23
+ securityDelta.netChange > 0 ||
24
+ functionalityDelta.netChange < 0) {
25
+ overallChange = "regressed";
26
+ }
27
+ else if (improved > 0 ||
28
+ securityDelta.netChange < 0 ||
29
+ functionalityDelta.netChange > 0) {
30
+ overallChange = "improved";
31
+ }
32
+ const recommendations = generateDiffRecommendations(moduleChanges, securityDelta, functionalityDelta);
33
+ return {
34
+ serverName: current.serverName,
35
+ baseline: {
36
+ version: extractVersion(baseline),
37
+ date: baseline.assessmentDate,
38
+ assessorVersion: baseline.assessorVersion,
39
+ },
40
+ current: {
41
+ version: extractVersion(current),
42
+ date: current.assessmentDate,
43
+ assessorVersion: current.assessorVersion,
44
+ },
45
+ summary: {
46
+ overallChange,
47
+ baselineStatus: baseline.overallStatus,
48
+ currentStatus: current.overallStatus,
49
+ modulesImproved: improved,
50
+ modulesRegressed: regressed,
51
+ modulesUnchanged: unchanged,
52
+ },
53
+ moduleChanges,
54
+ securityDelta,
55
+ functionalityDelta,
56
+ recommendations,
57
+ };
58
+ }
59
+ /**
60
+ * Compare individual module results
61
+ */
62
+ function compareModules(baseline, current) {
63
+ const changes = [];
64
+ // Compare core modules
65
+ const modules = [
66
+ {
67
+ name: "functionality",
68
+ getStatus: (a) => a.functionality?.status,
69
+ getScore: (a) => a.functionality
70
+ ? (a.functionality.workingTools / a.functionality.totalTools) * 100
71
+ : undefined,
72
+ },
73
+ {
74
+ name: "security",
75
+ getStatus: (a) => a.security?.status,
76
+ getScore: (a) => a.security
77
+ ? 100 -
78
+ (a.security.vulnerabilities.length /
79
+ Math.max(a.security.promptInjectionTests.length, 1)) *
80
+ 100
81
+ : undefined,
82
+ },
83
+ {
84
+ name: "documentation",
85
+ getStatus: (a) => a.documentation?.status,
86
+ },
87
+ {
88
+ name: "errorHandling",
89
+ getStatus: (a) => a.errorHandling?.status,
90
+ getScore: (a) => a.errorHandling?.metrics?.mcpComplianceScore,
91
+ },
92
+ {
93
+ name: "usability",
94
+ getStatus: (a) => a.usability?.status,
95
+ },
96
+ {
97
+ name: "mcpSpecCompliance",
98
+ getStatus: (a) => a.mcpSpecCompliance?.status,
99
+ getScore: (a) => a.mcpSpecCompliance?.complianceScore,
100
+ },
101
+ {
102
+ name: "aupCompliance",
103
+ getStatus: (a) => a.aupCompliance?.status,
104
+ },
105
+ {
106
+ name: "toolAnnotations",
107
+ getStatus: (a) => a.toolAnnotations?.status,
108
+ },
109
+ {
110
+ name: "manifestValidation",
111
+ getStatus: (a) => a.manifestValidation?.status,
112
+ },
113
+ {
114
+ name: "portability",
115
+ getStatus: (a) => a.portability?.status,
116
+ },
117
+ ];
118
+ for (const mod of modules) {
119
+ const baselineStatus = mod.getStatus(baseline);
120
+ const currentStatus = mod.getStatus(current);
121
+ // Skip if module wasn't run in either assessment
122
+ if (!baselineStatus && !currentStatus)
123
+ continue;
124
+ const baselineScore = mod.getScore?.(baseline);
125
+ const currentScore = mod.getScore?.(current);
126
+ const change = determineChange(baselineStatus || "NEED_MORE_INFO", currentStatus || "NEED_MORE_INFO", baselineScore, currentScore);
127
+ changes.push({
128
+ module: mod.name,
129
+ baselineStatus: baselineStatus || "NEED_MORE_INFO",
130
+ currentStatus: currentStatus || "NEED_MORE_INFO",
131
+ baselineScore,
132
+ currentScore,
133
+ change,
134
+ details: generateModuleDetails(mod.name, baselineStatus, currentStatus, baselineScore, currentScore),
135
+ });
136
+ }
137
+ return changes;
138
+ }
139
+ /**
140
+ * Determine if a module improved, regressed, or stayed the same
141
+ */
142
+ function determineChange(baselineStatus, currentStatus, baselineScore, currentScore) {
143
+ // Status-based change
144
+ const statusOrder = {
145
+ FAIL: 0,
146
+ NEED_MORE_INFO: 1,
147
+ PASS: 2,
148
+ };
149
+ const baselineRank = statusOrder[baselineStatus];
150
+ const currentRank = statusOrder[currentStatus];
151
+ if (currentRank > baselineRank)
152
+ return "improved";
153
+ if (currentRank < baselineRank)
154
+ return "regressed";
155
+ // Score-based change (if statuses are equal)
156
+ if (baselineScore !== undefined && currentScore !== undefined) {
157
+ const scoreDiff = currentScore - baselineScore;
158
+ if (scoreDiff > 5)
159
+ return "improved"; // 5% threshold
160
+ if (scoreDiff < -5)
161
+ return "regressed";
162
+ }
163
+ return "unchanged";
164
+ }
165
+ /**
166
+ * Generate human-readable details for a module change
167
+ */
168
+ function generateModuleDetails(_moduleName, baselineStatus, currentStatus, baselineScore, currentScore) {
169
+ const parts = [];
170
+ if (baselineStatus !== currentStatus) {
171
+ parts.push(`${baselineStatus || "N/A"} → ${currentStatus || "N/A"}`);
172
+ }
173
+ if (baselineScore !== undefined && currentScore !== undefined) {
174
+ const diff = currentScore - baselineScore;
175
+ const sign = diff > 0 ? "+" : "";
176
+ parts.push(`Score: ${baselineScore.toFixed(1)}% → ${currentScore.toFixed(1)}% (${sign}${diff.toFixed(1)}%)`);
177
+ }
178
+ if (parts.length === 0) {
179
+ return "No change";
180
+ }
181
+ return parts.join(", ");
182
+ }
183
+ /**
184
+ * Compare security results between assessments
185
+ */
186
+ function compareSecurityResults(baseline, current) {
187
+ const baselineVulns = new Set(baseline.security?.vulnerabilities || []);
188
+ const currentVulns = new Set(current.security?.vulnerabilities || []);
189
+ const newVulnerabilities = [];
190
+ const fixedVulnerabilities = [];
191
+ for (const vuln of currentVulns) {
192
+ if (!baselineVulns.has(vuln)) {
193
+ newVulnerabilities.push(vuln);
194
+ }
195
+ }
196
+ for (const vuln of baselineVulns) {
197
+ if (!currentVulns.has(vuln)) {
198
+ fixedVulnerabilities.push(vuln);
199
+ }
200
+ }
201
+ return {
202
+ newVulnerabilities,
203
+ fixedVulnerabilities,
204
+ netChange: newVulnerabilities.length - fixedVulnerabilities.length,
205
+ baselineCount: baselineVulns.size,
206
+ currentCount: currentVulns.size,
207
+ };
208
+ }
209
+ /**
210
+ * Compare functionality results between assessments
211
+ */
212
+ function compareFunctionalityResults(baseline, current) {
213
+ const baselineBroken = new Set(baseline.functionality?.brokenTools || []);
214
+ const currentBroken = new Set(current.functionality?.brokenTools || []);
215
+ const newBrokenTools = [];
216
+ const fixedTools = [];
217
+ for (const tool of currentBroken) {
218
+ if (!baselineBroken.has(tool)) {
219
+ newBrokenTools.push(tool);
220
+ }
221
+ }
222
+ for (const tool of baselineBroken) {
223
+ if (!currentBroken.has(tool)) {
224
+ fixedTools.push(tool);
225
+ }
226
+ }
227
+ const baselineWorking = baseline.functionality?.workingTools || 0;
228
+ const currentWorking = current.functionality?.workingTools || 0;
229
+ return {
230
+ newBrokenTools,
231
+ fixedTools,
232
+ netChange: currentWorking - baselineWorking,
233
+ baselineWorking,
234
+ currentWorking,
235
+ };
236
+ }
237
+ /**
238
+ * Generate recommendations based on the diff
239
+ */
240
+ function generateDiffRecommendations(moduleChanges, securityDelta, functionalityDelta) {
241
+ const recommendations = [];
242
+ // Security regressions are critical
243
+ if (securityDelta.newVulnerabilities.length > 0) {
244
+ recommendations.push(`CRITICAL: ${securityDelta.newVulnerabilities.length} new security vulnerabilities detected`);
245
+ for (const vuln of securityDelta.newVulnerabilities.slice(0, 3)) {
246
+ recommendations.push(` - ${vuln}`);
247
+ }
248
+ }
249
+ // Functionality regressions
250
+ if (functionalityDelta.newBrokenTools.length > 0) {
251
+ recommendations.push(`WARNING: ${functionalityDelta.newBrokenTools.length} tool(s) now broken`);
252
+ for (const tool of functionalityDelta.newBrokenTools.slice(0, 3)) {
253
+ recommendations.push(` - ${tool}`);
254
+ }
255
+ }
256
+ // Module regressions
257
+ const regressions = moduleChanges.filter((m) => m.change === "regressed");
258
+ if (regressions.length > 0) {
259
+ recommendations.push(`WARNING: ${regressions.length} module(s) regressed`);
260
+ for (const reg of regressions) {
261
+ recommendations.push(` - ${reg.module}: ${reg.details}`);
262
+ }
263
+ }
264
+ // Positive changes
265
+ if (securityDelta.fixedVulnerabilities.length > 0) {
266
+ recommendations.push(`IMPROVED: ${securityDelta.fixedVulnerabilities.length} vulnerabilities fixed`);
267
+ }
268
+ if (functionalityDelta.fixedTools.length > 0) {
269
+ recommendations.push(`IMPROVED: ${functionalityDelta.fixedTools.length} tool(s) now working`);
270
+ }
271
+ const improvements = moduleChanges.filter((m) => m.change === "improved");
272
+ if (improvements.length > 0) {
273
+ recommendations.push(`IMPROVED: ${improvements.length} module(s) improved`);
274
+ }
275
+ if (recommendations.length === 0) {
276
+ recommendations.push("No significant changes detected between versions");
277
+ }
278
+ return recommendations;
279
+ }
280
+ /**
281
+ * Extract version from assessment (if available from manifest)
282
+ */
283
+ function extractVersion(assessment) {
284
+ // Try to get version from manifest validation
285
+ if (assessment.manifestValidation?.manifestVersion) {
286
+ return assessment.manifestValidation.manifestVersion;
287
+ }
288
+ return undefined;
289
+ }
@@ -241,6 +241,16 @@ export interface UsabilityMetrics {
241
241
  overallScore: number;
242
242
  };
243
243
  }
244
+ /** Tool definition with schema from MCP tools/list response */
245
+ export interface DiscoveredTool {
246
+ name: string;
247
+ description?: string;
248
+ inputSchema?: {
249
+ type: string;
250
+ properties?: Record<string, unknown>;
251
+ required?: string[];
252
+ };
253
+ }
244
254
  export interface FunctionalityAssessment {
245
255
  totalTools: number;
246
256
  testedTools: number;
@@ -250,6 +260,8 @@ export interface FunctionalityAssessment {
250
260
  status: AssessmentStatus;
251
261
  explanation: string;
252
262
  toolResults: ToolTestResult[];
263
+ /** Raw tool definitions with inputSchema from MCP server */
264
+ tools?: DiscoveredTool[];
253
265
  }
254
266
  export interface SecurityAssessment {
255
267
  promptInjectionTests: SecurityTestResult[];
@@ -477,6 +489,7 @@ export interface MCPDirectoryAssessment {
477
489
  manifestValidation?: ManifestValidationAssessment;
478
490
  portability?: PortabilityAssessment;
479
491
  externalAPIScanner?: ExternalAPIScannerAssessment;
492
+ authentication?: AuthenticationAssessment;
480
493
  overallStatus: AssessmentStatus;
481
494
  summary: string;
482
495
  recommendations: string[];
@@ -635,6 +648,18 @@ export interface ManifestJsonSchema {
635
648
  icon?: string;
636
649
  homepage?: string;
637
650
  keywords?: string[];
651
+ privacy_policies?: string[];
652
+ }
653
+ /**
654
+ * Privacy Policy URL Validation Result
655
+ * Validates that privacy_policies URLs are accessible
656
+ */
657
+ export interface PrivacyPolicyValidation {
658
+ url: string;
659
+ accessible: boolean;
660
+ statusCode?: number;
661
+ contentType?: string;
662
+ error?: string;
638
663
  }
639
664
  export interface ManifestValidationResult {
640
665
  field: string;
@@ -651,6 +676,12 @@ export interface ManifestValidationAssessment {
651
676
  hasIcon: boolean;
652
677
  hasRequiredFields: boolean;
653
678
  missingFields: string[];
679
+ /** Privacy policy URL validation results */
680
+ privacyPolicies?: {
681
+ declared: string[];
682
+ validationResults: PrivacyPolicyValidation[];
683
+ allAccessible: boolean;
684
+ };
654
685
  status: AssessmentStatus;
655
686
  explanation: string;
656
687
  recommendations: string[];
@@ -692,6 +723,27 @@ export interface ExternalAPIScannerAssessment {
692
723
  explanation: string;
693
724
  recommendations: string[];
694
725
  }
726
+ export type AuthMethod = "oauth" | "api_key" | "none" | "unknown";
727
+ export interface AuthAppropriateness {
728
+ isAppropriate: boolean;
729
+ concerns: string[];
730
+ explanation: string;
731
+ }
732
+ export interface AuthenticationAssessment {
733
+ authMethod: AuthMethod;
734
+ hasLocalDependencies: boolean;
735
+ transportType: string;
736
+ appropriateness: AuthAppropriateness;
737
+ recommendation: string;
738
+ detectedPatterns: {
739
+ oauthIndicators: string[];
740
+ localResourceIndicators: string[];
741
+ apiKeyIndicators: string[];
742
+ };
743
+ status: AssessmentStatus;
744
+ explanation: string;
745
+ recommendations: string[];
746
+ }
695
747
  export declare const PROMPT_INJECTION_TESTS: Omit<SecurityTestResult, "vulnerable" | "evidence">[];
696
748
  /**
697
749
  * Claude Code Bridge Configuration
@@ -739,6 +791,7 @@ export interface AssessmentConfiguration {
739
791
  manifestValidation?: boolean;
740
792
  portability?: boolean;
741
793
  externalAPIScanner?: boolean;
794
+ authentication?: boolean;
742
795
  };
743
796
  }
744
797
  /**