@bryan-thompson/inspector-assessment 1.7.1 → 1.7.2
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/client/dist/assets/{OAuthCallback-cGhwkoyY.js → OAuthCallback-Dk69OAHS.js} +1 -1
- package/client/dist/assets/{OAuthDebugCallback-2rmUqser.js → OAuthDebugCallback-Do2NIUkY.js} +1 -1
- package/client/dist/assets/{index-Bj7kEsw0.css → index-B9Z2VpMu.css} +1 -1
- package/client/dist/assets/{index-BnFixpvH.js → index-BZfyfKpR.js} +1283 -676
- package/client/dist/index.html +2 -2
- package/client/lib/services/assessment/lib/concurrencyLimit.d.ts +20 -0
- package/client/lib/services/assessment/lib/concurrencyLimit.d.ts.map +1 -0
- package/client/lib/services/assessment/lib/concurrencyLimit.js +51 -0
- package/client/lib/services/assessment/modules/ErrorHandlingAssessor.d.ts.map +1 -1
- package/client/lib/services/assessment/modules/ErrorHandlingAssessor.js +14 -4
- package/client/lib/services/assessment/modules/FunctionalityAssessor.d.ts.map +1 -1
- package/client/lib/services/assessment/modules/FunctionalityAssessor.js +15 -5
- package/client/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
- package/client/lib/services/assessment/modules/SecurityAssessor.js +15 -5
- package/package.json +5 -5
- package/client/README.md +0 -50
package/client/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-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BZfyfKpR.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B9Z2VpMu.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root" class="w-full"></div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple concurrency limiter for parallel async operations
|
|
3
|
+
* Provides the same interface as p-limit but is CJS-compatible
|
|
4
|
+
*/
|
|
5
|
+
export type LimitFunction = <T>(fn: () => Promise<T>) => Promise<T>;
|
|
6
|
+
/**
|
|
7
|
+
* Creates a concurrency limiter that allows only a specified number
|
|
8
|
+
* of async operations to run simultaneously
|
|
9
|
+
*
|
|
10
|
+
* @param concurrency - Maximum number of concurrent operations
|
|
11
|
+
* @returns A function that wraps async operations with the concurrency limit
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const limit = createConcurrencyLimit(5);
|
|
15
|
+
* const results = await Promise.all(
|
|
16
|
+
* items.map(item => limit(() => processItem(item)))
|
|
17
|
+
* );
|
|
18
|
+
*/
|
|
19
|
+
export declare function createConcurrencyLimit(concurrency: number): LimitFunction;
|
|
20
|
+
//# sourceMappingURL=concurrencyLimit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrencyLimit.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/lib/concurrencyLimit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAyCzE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple concurrency limiter for parallel async operations
|
|
3
|
+
* Provides the same interface as p-limit but is CJS-compatible
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates a concurrency limiter that allows only a specified number
|
|
7
|
+
* of async operations to run simultaneously
|
|
8
|
+
*
|
|
9
|
+
* @param concurrency - Maximum number of concurrent operations
|
|
10
|
+
* @returns A function that wraps async operations with the concurrency limit
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const limit = createConcurrencyLimit(5);
|
|
14
|
+
* const results = await Promise.all(
|
|
15
|
+
* items.map(item => limit(() => processItem(item)))
|
|
16
|
+
* );
|
|
17
|
+
*/
|
|
18
|
+
export function createConcurrencyLimit(concurrency) {
|
|
19
|
+
if (concurrency < 1) {
|
|
20
|
+
throw new Error("Concurrency must be at least 1");
|
|
21
|
+
}
|
|
22
|
+
let activeCount = 0;
|
|
23
|
+
const queue = [];
|
|
24
|
+
const next = () => {
|
|
25
|
+
if (activeCount < concurrency && queue.length > 0) {
|
|
26
|
+
const { fn, resolve, reject } = queue.shift();
|
|
27
|
+
activeCount++;
|
|
28
|
+
fn()
|
|
29
|
+
.then((result) => {
|
|
30
|
+
activeCount--;
|
|
31
|
+
resolve(result);
|
|
32
|
+
next();
|
|
33
|
+
})
|
|
34
|
+
.catch((error) => {
|
|
35
|
+
activeCount--;
|
|
36
|
+
reject(error);
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return (fn) => {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
queue.push({
|
|
44
|
+
fn: fn,
|
|
45
|
+
resolve: resolve,
|
|
46
|
+
reject,
|
|
47
|
+
});
|
|
48
|
+
next();
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorHandlingAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/ErrorHandlingAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EAIxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"ErrorHandlingAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/ErrorHandlingAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,uBAAuB,EAIxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,qBAAa,qBAAsB,SAAQ,YAAY;IAC/C,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA8D1E,OAAO,CAAC,qBAAqB;YA8Cf,qBAAqB;YAuBrB,qBAAqB;YAmGrB,cAAc;YAmFd,iBAAiB;YA8DjB,kBAAkB;IA6DhC,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,uBAAuB;IAgC/B,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,uBAAuB;IA4B/B,OAAO,CAAC,gBAAgB;IAoGxB,OAAO,CAAC,4BAA4B;IAapC,OAAO,CAAC,mBAAmB;IAuE3B,OAAO,CAAC,uBAAuB;CA4ChC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Tests error handling and input validation
|
|
4
4
|
*/
|
|
5
5
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
6
|
+
import { createConcurrencyLimit } from "../lib/concurrencyLimit.js";
|
|
6
7
|
export class ErrorHandlingAssessor extends BaseAssessor {
|
|
7
8
|
async assess(context) {
|
|
8
9
|
this.log("Starting error handling assessment");
|
|
@@ -10,14 +11,23 @@ export class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
10
11
|
let passedTests = 0;
|
|
11
12
|
// Test a sample of tools for error handling
|
|
12
13
|
const toolsToTest = this.selectToolsForTesting(context.tools);
|
|
13
|
-
|
|
14
|
+
// Parallel tool testing with concurrency limit
|
|
15
|
+
const concurrency = this.config.maxParallelTests ?? 5;
|
|
16
|
+
const limit = createConcurrencyLimit(concurrency);
|
|
17
|
+
this.log(`Testing ${toolsToTest.length} tools for error handling with concurrency limit of ${concurrency}`);
|
|
18
|
+
const allToolTests = await Promise.all(toolsToTest.map((tool) => limit(async () => {
|
|
14
19
|
const toolTests = await this.testToolErrorHandling(tool, context.callTool);
|
|
15
|
-
testDetails.push(...toolTests);
|
|
16
|
-
passedTests += toolTests.filter((t) => t.passed).length;
|
|
17
20
|
// Add delay between tests to avoid rate limiting
|
|
18
|
-
if (this.config.delayBetweenTests &&
|
|
21
|
+
if (this.config.delayBetweenTests &&
|
|
22
|
+
this.config.delayBetweenTests > 0) {
|
|
19
23
|
await this.sleep(this.config.delayBetweenTests);
|
|
20
24
|
}
|
|
25
|
+
return toolTests;
|
|
26
|
+
})));
|
|
27
|
+
// Post-process results after parallel execution
|
|
28
|
+
for (const toolTests of allToolTests) {
|
|
29
|
+
testDetails.push(...toolTests);
|
|
30
|
+
passedTests += toolTests.filter((t) => t.passed).length;
|
|
21
31
|
}
|
|
22
32
|
this.testCount = testDetails.length;
|
|
23
33
|
const metrics = this.calculateMetrics(testDetails, passedTests);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FunctionalityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/FunctionalityAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAkB,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"FunctionalityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/FunctionalityAssessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAkB,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAI9D,qBAAa,qBAAsB,SAAQ,YAAY;IACrD;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoCvB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC;YAiF5D,QAAQ;IA6EtB,OAAO,CAAC,qBAAqB;IA2B7B,OAAO,CAAC,kBAAkB;IA0FnB,iBAAiB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO;IAI9C,OAAO,CAAC,mBAAmB;CA+B5B"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
6
6
|
import { ResponseValidator } from "../ResponseValidator.js";
|
|
7
|
+
import { createConcurrencyLimit } from "../lib/concurrencyLimit.js";
|
|
7
8
|
export class FunctionalityAssessor extends BaseAssessor {
|
|
8
9
|
/**
|
|
9
10
|
* Select tools for testing based on configuration
|
|
@@ -38,21 +39,30 @@ export class FunctionalityAssessor extends BaseAssessor {
|
|
|
38
39
|
let workingTools = 0;
|
|
39
40
|
// Select tools for testing
|
|
40
41
|
const toolsToTest = this.selectToolsForTesting(context.tools);
|
|
41
|
-
|
|
42
|
+
// Parallel tool testing with concurrency limit
|
|
43
|
+
const concurrency = this.config.maxParallelTests ?? 5;
|
|
44
|
+
const limit = createConcurrencyLimit(concurrency);
|
|
45
|
+
this.log(`Testing ${toolsToTest.length} tools with concurrency limit of ${concurrency}`);
|
|
46
|
+
const results = await Promise.all(toolsToTest.map((tool) => limit(async () => {
|
|
42
47
|
this.testCount++;
|
|
43
48
|
const result = await this.testTool(tool, context.callTool);
|
|
44
|
-
toolResults.push(result);
|
|
45
49
|
// Add delay between tests to avoid rate limiting
|
|
46
|
-
if (this.config.delayBetweenTests &&
|
|
50
|
+
if (this.config.delayBetweenTests &&
|
|
51
|
+
this.config.delayBetweenTests > 0) {
|
|
47
52
|
await this.sleep(this.config.delayBetweenTests);
|
|
48
53
|
}
|
|
54
|
+
return result;
|
|
55
|
+
})));
|
|
56
|
+
// Post-process results after parallel execution
|
|
57
|
+
for (const result of results) {
|
|
58
|
+
toolResults.push(result);
|
|
49
59
|
if (result.status === "working") {
|
|
50
60
|
workingTools++;
|
|
51
61
|
}
|
|
52
62
|
else if (result.status === "broken") {
|
|
53
|
-
brokenTools.push(
|
|
63
|
+
brokenTools.push(result.toolName);
|
|
54
64
|
if (this.config.skipBrokenTools) {
|
|
55
|
-
this.log(`Skipping further tests for broken tool: ${
|
|
65
|
+
this.log(`Skipping further tests for broken tool: ${result.toolName}`);
|
|
56
66
|
}
|
|
57
67
|
}
|
|
58
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/SecurityAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"SecurityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/SecurityAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAU9D,qBAAa,gBAAiB,SAAQ,YAAY;IAC1C,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuFrE;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;;;OAIG;YACW,yBAAyB;IAgHvC;;;;OAIG;YACW,qBAAqB;IAwGnC;;OAEG;YACW,WAAW;IA2HzB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAkDzB;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAmDtC;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAgClC;;;OAGG;IACH,OAAO,CAAC,eAAe;IA6HvB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAiE7B;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAqC5B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAkC5B;;OAEG;YACW,+BAA+B;IAiC7C;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAYjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAkEnC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuI3B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,oBAAoB;IAiM5B;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IAiDhC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;IAoE5B;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;OAGG;IACH,OAAO,CAAC,eAAe;IASvB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAmB3B"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
9
9
|
import { getAllAttackPatterns, getPayloadsForAttack, } from "../../../lib/securityPatterns.js";
|
|
10
10
|
import { ToolClassifier, ToolCategory } from "../ToolClassifier.js";
|
|
11
|
+
import { createConcurrencyLimit } from "../lib/concurrencyLimit.js";
|
|
11
12
|
export class SecurityAssessor extends BaseAssessor {
|
|
12
13
|
async assess(context) {
|
|
13
14
|
// Select tools for testing first
|
|
@@ -108,8 +109,12 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
108
109
|
const attackPatterns = getAllAttackPatterns();
|
|
109
110
|
// Select tools for testing
|
|
110
111
|
const toolsToTest = this.selectToolsForTesting(context.tools);
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
// Parallel tool testing with concurrency limit
|
|
113
|
+
const concurrency = this.config.maxParallelTests ?? 5;
|
|
114
|
+
const limit = createConcurrencyLimit(concurrency);
|
|
115
|
+
this.log(`Starting ADVANCED security assessment - testing ${toolsToTest.length} tools with ${attackPatterns.length} security patterns (~${toolsToTest.length * attackPatterns.length * 3} tests) [concurrency: ${concurrency}]`);
|
|
116
|
+
const allToolResults = await Promise.all(toolsToTest.map((tool) => limit(async () => {
|
|
117
|
+
const toolResults = [];
|
|
113
118
|
// Tools with no input parameters can't be exploited via payload injection
|
|
114
119
|
// Add passing results so they appear in the UI
|
|
115
120
|
if (!this.hasInputParameters(tool)) {
|
|
@@ -119,7 +124,7 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
119
124
|
const payloads = getPayloadsForAttack(attackPattern.attackName);
|
|
120
125
|
// Add one passing result per payload type
|
|
121
126
|
for (const payload of payloads) {
|
|
122
|
-
|
|
127
|
+
toolResults.push({
|
|
123
128
|
testName: attackPattern.attackName,
|
|
124
129
|
description: payload.description,
|
|
125
130
|
payload: payload.payload,
|
|
@@ -130,7 +135,7 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
130
135
|
});
|
|
131
136
|
}
|
|
132
137
|
}
|
|
133
|
-
|
|
138
|
+
return toolResults;
|
|
134
139
|
}
|
|
135
140
|
this.log(`Testing ${tool.name} with all attack patterns`);
|
|
136
141
|
// Test with each attack type (all patterns in advanced mode)
|
|
@@ -142,7 +147,7 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
142
147
|
this.testCount++;
|
|
143
148
|
try {
|
|
144
149
|
const result = await this.testPayload(tool, attackPattern.attackName, payload, context.callTool);
|
|
145
|
-
|
|
150
|
+
toolResults.push(result);
|
|
146
151
|
if (result.vulnerable) {
|
|
147
152
|
this.log(`🚨 VULNERABILITY: ${tool.name} - ${attackPattern.attackName} (${payload.payloadType}: ${payload.description})`);
|
|
148
153
|
}
|
|
@@ -156,6 +161,11 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
156
161
|
}
|
|
157
162
|
}
|
|
158
163
|
}
|
|
164
|
+
return toolResults;
|
|
165
|
+
})));
|
|
166
|
+
// Flatten all tool results into the main results array
|
|
167
|
+
for (const toolResults of allToolResults) {
|
|
168
|
+
results.push(...toolResults);
|
|
159
169
|
}
|
|
160
170
|
this.log(`ADVANCED security assessment complete: ${results.length} tests executed, ${results.filter((r) => r.vulnerable).length} vulnerabilities found`);
|
|
161
171
|
return results;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Enhanced MCP Inspector with comprehensive assessment capabilities for server validation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bryan Thompson <bryan@triepod.ai>",
|
|
@@ -74,14 +74,14 @@
|
|
|
74
74
|
"access": "public"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@bryan-thompson/inspector-assessment-cli": "^1.
|
|
78
|
-
"@bryan-thompson/inspector-assessment-client": "^1.
|
|
79
|
-
"@bryan-thompson/inspector-assessment-server": "^1.
|
|
80
|
-
"@esbuild/darwin-arm64": "^0.27.1",
|
|
77
|
+
"@bryan-thompson/inspector-assessment-cli": "^1.7.1",
|
|
78
|
+
"@bryan-thompson/inspector-assessment-client": "^1.7.1",
|
|
79
|
+
"@bryan-thompson/inspector-assessment-server": "^1.7.1",
|
|
81
80
|
"@modelcontextprotocol/sdk": "^1.23.0",
|
|
82
81
|
"concurrently": "^9.2.0",
|
|
83
82
|
"node-fetch": "^3.3.2",
|
|
84
83
|
"open": "^10.2.0",
|
|
84
|
+
"p-limit": "^7.2.0",
|
|
85
85
|
"shell-quote": "^1.8.3",
|
|
86
86
|
"spawn-rx": "^5.1.2",
|
|
87
87
|
"ts-node": "^10.9.2",
|
package/client/README.md
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# React + TypeScript + Vite
|
|
2
|
-
|
|
3
|
-
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
-
|
|
5
|
-
Currently, two official plugins are available:
|
|
6
|
-
|
|
7
|
-
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
|
8
|
-
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
-
|
|
10
|
-
## Expanding the ESLint configuration
|
|
11
|
-
|
|
12
|
-
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
|
|
13
|
-
|
|
14
|
-
- Configure the top-level `parserOptions` property like this:
|
|
15
|
-
|
|
16
|
-
```js
|
|
17
|
-
export default tseslint.config({
|
|
18
|
-
languageOptions: {
|
|
19
|
-
// other options...
|
|
20
|
-
parserOptions: {
|
|
21
|
-
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
|
|
22
|
-
tsconfigRootDir: import.meta.dirname,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
|
|
29
|
-
- Optionally add `...tseslint.configs.stylisticTypeChecked`
|
|
30
|
-
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
// eslint.config.js
|
|
34
|
-
import react from "eslint-plugin-react";
|
|
35
|
-
|
|
36
|
-
export default tseslint.config({
|
|
37
|
-
// Set the react version
|
|
38
|
-
settings: { react: { version: "18.3" } },
|
|
39
|
-
plugins: {
|
|
40
|
-
// Add the react plugin
|
|
41
|
-
react,
|
|
42
|
-
},
|
|
43
|
-
rules: {
|
|
44
|
-
// other rules...
|
|
45
|
-
// Enable its recommended rules
|
|
46
|
-
...react.configs.recommended.rules,
|
|
47
|
-
...react.configs["jsx-runtime"].rules,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
```
|