@bryan-thompson/inspector-assessment 1.0.0 → 1.1.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/README.md +68 -33
- package/client/dist/assets/{OAuthCallback-CLEJW5KO.js → OAuthCallback-aV2t2Zmo.js} +1 -1
- package/client/dist/assets/{OAuthDebugCallback-B154gAVm.js → OAuthDebugCallback-Ca01948b.js} +1 -1
- package/client/dist/assets/{index-EfKh2svk.js → index-DrU0QB6A.js} +91 -32
- package/client/dist/index.html +1 -1
- package/package.json +1 -1
- package/server/build/index.js +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# MCP Inspector Assessment
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@bryan-thompson/inspector-assessment)
|
|
4
|
+
[](https://www.npmjs.com/package/@bryan-thompson/inspector-assessment)
|
|
5
|
+
|
|
3
6
|
The MCP inspector is a developer tool for testing and debugging MCP servers with comprehensive assessment capabilities for validating server functionality, security, documentation, and compliance.
|
|
4
7
|
|
|
5
8
|

|
|
@@ -42,6 +45,18 @@ bunx @bryan-thompson/inspector-assessment
|
|
|
42
45
|
|
|
43
46
|
The web interface will open at http://localhost:6274
|
|
44
47
|
|
|
48
|
+
## For MCP Directory Reviewers
|
|
49
|
+
|
|
50
|
+
If you're reviewing MCP servers for the Anthropic MCP Directory, see our **[Reviewer Quick Start Guide](docs/REVIEWER_QUICK_START.md)** for:
|
|
51
|
+
|
|
52
|
+
- **60-second fast screening** workflow for approve/reject decisions
|
|
53
|
+
- **5-minute detailed review** process for borderline cases
|
|
54
|
+
- **Common pitfalls** explanation (false positives in security, informational vs scored tests)
|
|
55
|
+
- **Decision matrix** with clear approval criteria
|
|
56
|
+
- **Fast CLI analysis** commands for troubleshooting
|
|
57
|
+
|
|
58
|
+
The quick start guide is optimized for fast reviewer onboarding and provides clear guidance on interpreting assessment results.
|
|
59
|
+
|
|
45
60
|
## About This Fork
|
|
46
61
|
|
|
47
62
|
This is an enhanced fork of [Anthropic's MCP Inspector](https://github.com/modelcontextprotocol/inspector) with significantly expanded assessment capabilities for MCP server validation and testing.
|
|
@@ -49,6 +64,8 @@ This is an enhanced fork of [Anthropic's MCP Inspector](https://github.com/model
|
|
|
49
64
|
**Original Repository**: https://github.com/modelcontextprotocol/inspector
|
|
50
65
|
**Our Enhanced Fork**: https://github.com/triepod-ai/inspector-assessment
|
|
51
66
|
|
|
67
|
+
**⚠️ Important**: This is a published fork with assessment enhancements. If you want the official Anthropic inspector without assessment features, use `npx @modelcontextprotocol/inspector`.
|
|
68
|
+
|
|
52
69
|
### What We Added
|
|
53
70
|
|
|
54
71
|
We've built a comprehensive assessment framework on top of the original inspector that transforms it from a debugging tool into a full validation suite for MCP servers. Our enhancements focus on accuracy, depth, and actionable insights for MCP server developers.
|
|
@@ -65,13 +82,14 @@ We've built a comprehensive assessment framework on top of the original inspecto
|
|
|
65
82
|
|
|
66
83
|
Our enhanced fork maintains high code quality standards with comprehensive testing and validation:
|
|
67
84
|
|
|
68
|
-
- **Test Coverage**: ✅
|
|
85
|
+
- **Test Coverage**: ✅ 582/582 tests passing (100% pass rate)
|
|
69
86
|
- **Assessment Module Tests**: 208 tests specifically validating our assessment enhancements
|
|
70
87
|
- Business logic error detection with confidence scoring
|
|
71
88
|
- Progressive complexity testing (2 levels: minimal → simple)
|
|
72
89
|
- Context-aware security testing with zero false positives
|
|
73
90
|
- Realistic test data generation and boundary testing
|
|
74
|
-
- **Total Project Tests**:
|
|
91
|
+
- **Total Project Tests**: 582 tests including assessment modules, UI components, and core inspector functionality
|
|
92
|
+
- All tests updated to reflect comprehensive mode (18 security patterns × 3 payloads per tool)
|
|
75
93
|
- Test files: `client/src/services/__tests__/` and `client/src/services/assessment/__tests__/`
|
|
76
94
|
- **Code Quality**: ✅ Production code uses proper TypeScript types
|
|
77
95
|
- 229 lint issues remaining (down 18% from 280 after recent cleanup)
|
|
@@ -88,7 +106,7 @@ Our enhanced fork maintains high code quality standards with comprehensive testi
|
|
|
88
106
|
**Testing Commands**:
|
|
89
107
|
|
|
90
108
|
```bash
|
|
91
|
-
npm test # Run all
|
|
109
|
+
npm test # Run all 582 tests
|
|
92
110
|
npm test -- assessment # Run all 208 assessment module tests
|
|
93
111
|
npm test -- assessmentService # Run assessment service integration tests (54 tests)
|
|
94
112
|
npm test -- SecurityAssessor # Run security assessment tests (16 tests)
|
|
@@ -417,7 +435,7 @@ Our assessment capabilities are backed by a comprehensive test suite that valida
|
|
|
417
435
|
|
|
418
436
|
**Test Coverage Summary**:
|
|
419
437
|
|
|
420
|
-
- **
|
|
438
|
+
- **582 passing tests** across all project modules (100% pass rate)
|
|
421
439
|
- **208 assessment module tests** specifically created for validation of our enhancements
|
|
422
440
|
|
|
423
441
|
#### Assessment Module Test Breakdown
|
|
@@ -472,14 +490,15 @@ These 208 tests specifically validate:
|
|
|
472
490
|
- **Optimization Tests**: Boundary scenario conditional generation, progressive complexity efficiency
|
|
473
491
|
- **Test Files**: Located in `client/src/services/__tests__/` and `client/src/services/assessment/__tests__/`
|
|
474
492
|
- **Recent Improvements**:
|
|
475
|
-
- Achieved 100% test pass rate (
|
|
493
|
+
- Achieved 100% test pass rate (582 passing, 0 failing) - 2025-10-11
|
|
494
|
+
- Updated all tests for comprehensive mode (18 security patterns × 3 payloads) - 2025-10-11
|
|
476
495
|
- Fixed all failing tests after upstream sync - 2025-10-04
|
|
477
496
|
- Added boundary testing optimization validation - 2025-10-05
|
|
478
497
|
|
|
479
498
|
**Running the Test Suite**:
|
|
480
499
|
|
|
481
500
|
```bash
|
|
482
|
-
npm test # Run all
|
|
501
|
+
npm test # Run all 582 tests
|
|
483
502
|
npm test -- assessmentService # Run main assessment tests
|
|
484
503
|
npm test -- FunctionalityAssessor # Run specific assessor tests
|
|
485
504
|
npm test -- SecurityAssessor # Run security tests
|
|
@@ -503,13 +522,15 @@ Programmatically run assessments using the CLI:
|
|
|
503
522
|
|
|
504
523
|
```bash
|
|
505
524
|
# Run full assessment
|
|
506
|
-
|
|
525
|
+
mcp-inspector-assess-cli node build/index.js --assess
|
|
526
|
+
# or with npx
|
|
527
|
+
npx @bryan-thompson/inspector-assessment-cli node build/index.js --assess
|
|
507
528
|
|
|
508
529
|
# Run specific category
|
|
509
|
-
|
|
530
|
+
mcp-inspector-assess-cli node build/index.js --assess functionality
|
|
510
531
|
|
|
511
532
|
# Export assessment results
|
|
512
|
-
|
|
533
|
+
mcp-inspector-assess-cli node build/index.js --assess --output assessment-report.json
|
|
513
534
|
```
|
|
514
535
|
|
|
515
536
|
## Running the Inspector
|
|
@@ -523,14 +544,16 @@ npx @modelcontextprotocol/inspector --cli node build/index.js --assess --output
|
|
|
523
544
|
To get up and running right away with the UI, just execute the following:
|
|
524
545
|
|
|
525
546
|
```bash
|
|
526
|
-
|
|
547
|
+
bunx @bryan-thompson/inspector-assessment
|
|
548
|
+
# or with npx
|
|
549
|
+
npx @bryan-thompson/inspector-assessment
|
|
527
550
|
```
|
|
528
551
|
|
|
529
552
|
The server will start up and the UI will be accessible at `http://localhost:6274`.
|
|
530
553
|
|
|
531
554
|
### Docker Container
|
|
532
555
|
|
|
533
|
-
|
|
556
|
+
**Note**: Docker container is not yet available for `@bryan-thompson/inspector-assessment`. The Docker image below is for the upstream inspector only (without assessment features):
|
|
534
557
|
|
|
535
558
|
```bash
|
|
536
559
|
docker run --rm --network host -p 6274:6274 -p 6277:6277 ghcr.io/modelcontextprotocol/inspector:latest
|
|
@@ -538,32 +561,34 @@ docker run --rm --network host -p 6274:6274 -p 6277:6277 ghcr.io/modelcontextpro
|
|
|
538
561
|
|
|
539
562
|
### From an MCP server repository
|
|
540
563
|
|
|
541
|
-
To inspect an MCP server implementation, there's no need to clone this repo. Instead, use `npx`. For example, if your server is built at `build/index.js`:
|
|
564
|
+
To inspect an MCP server implementation, there's no need to clone this repo. Instead, use `bunx` or `npx`. For example, if your server is built at `build/index.js`:
|
|
542
565
|
|
|
543
566
|
```bash
|
|
544
|
-
|
|
567
|
+
bunx @bryan-thompson/inspector-assessment node build/index.js
|
|
568
|
+
# or with npx
|
|
569
|
+
npx @bryan-thompson/inspector-assessment node build/index.js
|
|
545
570
|
```
|
|
546
571
|
|
|
547
572
|
You can pass both arguments and environment variables to your MCP server. Arguments are passed directly to your server, while environment variables can be set using the `-e` flag:
|
|
548
573
|
|
|
549
574
|
```bash
|
|
550
575
|
# Pass arguments only
|
|
551
|
-
|
|
576
|
+
bunx @bryan-thompson/inspector-assessment node build/index.js arg1 arg2
|
|
552
577
|
|
|
553
578
|
# Pass environment variables only
|
|
554
|
-
|
|
579
|
+
bunx @bryan-thompson/inspector-assessment -e key=value -e key2=$VALUE2 node build/index.js
|
|
555
580
|
|
|
556
581
|
# Pass both environment variables and arguments
|
|
557
|
-
|
|
582
|
+
bunx @bryan-thompson/inspector-assessment -e key=value -e key2=$VALUE2 node build/index.js arg1 arg2
|
|
558
583
|
|
|
559
584
|
# Use -- to separate inspector flags from server arguments
|
|
560
|
-
|
|
585
|
+
bunx @bryan-thompson/inspector-assessment -e key=$VALUE -- node build/index.js -e server-flag
|
|
561
586
|
```
|
|
562
587
|
|
|
563
588
|
The inspector runs both an MCP Inspector (MCPI) client UI (default port 6274) and an MCP Proxy (MCPP) server (default port 6277). Open the MCPI client UI in your browser to use the inspector. (These ports are derived from the T9 dialpad mapping of MCPI and MCPP respectively, as a mnemonic). You can customize the ports if needed:
|
|
564
589
|
|
|
565
590
|
```bash
|
|
566
|
-
CLIENT_PORT=8080 SERVER_PORT=9000
|
|
591
|
+
CLIENT_PORT=8080 SERVER_PORT=9000 bunx @bryan-thompson/inspector-assessment node build/index.js
|
|
567
592
|
```
|
|
568
593
|
|
|
569
594
|
For more details on ways to use the inspector, see the [Inspector section of the MCP docs site](https://modelcontextprotocol.io/docs/tools/inspector). For help with debugging, see the [Debugging guide](https://modelcontextprotocol.io/docs/tools/debugging).
|
|
@@ -748,7 +773,7 @@ These settings can be adjusted in real-time through the UI and will persist acro
|
|
|
748
773
|
The inspector also supports configuration files to store settings for different MCP servers. This is useful when working with multiple servers or complex configurations:
|
|
749
774
|
|
|
750
775
|
```bash
|
|
751
|
-
|
|
776
|
+
bunx @bryan-thompson/inspector-assessment --config path/to/config.json --server everything
|
|
752
777
|
```
|
|
753
778
|
|
|
754
779
|
Example server configuration file:
|
|
@@ -827,7 +852,7 @@ You can launch the inspector without specifying a server name if your config has
|
|
|
827
852
|
|
|
828
853
|
```bash
|
|
829
854
|
# Automatically uses "my-server" if it's the only one
|
|
830
|
-
|
|
855
|
+
bunx @bryan-thompson/inspector-assessment --config mcp.json
|
|
831
856
|
```
|
|
832
857
|
|
|
833
858
|
2. **A server named "default-server"** - automatically selected:
|
|
@@ -900,47 +925,47 @@ npm start
|
|
|
900
925
|
CLI mode enables programmatic interaction with MCP servers from the command line, ideal for scripting, automation, and integration with coding assistants. This creates an efficient feedback loop for MCP server development.
|
|
901
926
|
|
|
902
927
|
```bash
|
|
903
|
-
|
|
928
|
+
mcp-inspector-assess-cli node build/index.js
|
|
904
929
|
```
|
|
905
930
|
|
|
906
931
|
The CLI mode supports most operations across tools, resources, and prompts. A few examples:
|
|
907
932
|
|
|
908
933
|
```bash
|
|
909
934
|
# Basic usage
|
|
910
|
-
|
|
935
|
+
mcp-inspector-assess-cli node build/index.js
|
|
911
936
|
|
|
912
937
|
# With config file
|
|
913
|
-
|
|
938
|
+
mcp-inspector-assess-cli --config path/to/config.json --server myserver
|
|
914
939
|
|
|
915
940
|
# List available tools
|
|
916
|
-
|
|
941
|
+
mcp-inspector-assess-cli node build/index.js --method tools/list
|
|
917
942
|
|
|
918
943
|
# Call a specific tool
|
|
919
|
-
|
|
944
|
+
mcp-inspector-assess-cli node build/index.js --method tools/call --tool-name mytool --tool-arg key=value --tool-arg another=value2
|
|
920
945
|
|
|
921
946
|
# Call a tool with JSON arguments
|
|
922
|
-
|
|
947
|
+
mcp-inspector-assess-cli node build/index.js --method tools/call --tool-name mytool --tool-arg 'options={"format": "json", "max_tokens": 100}'
|
|
923
948
|
|
|
924
949
|
# List available resources
|
|
925
|
-
|
|
950
|
+
mcp-inspector-assess-cli node build/index.js --method resources/list
|
|
926
951
|
|
|
927
952
|
# List available prompts
|
|
928
|
-
|
|
953
|
+
mcp-inspector-assess-cli node build/index.js --method prompts/list
|
|
929
954
|
|
|
930
955
|
# Connect to a remote MCP server (default is SSE transport)
|
|
931
|
-
|
|
956
|
+
mcp-inspector-assess-cli https://my-mcp-server.example.com
|
|
932
957
|
|
|
933
958
|
# Connect to a remote MCP server (with Streamable HTTP transport)
|
|
934
|
-
|
|
959
|
+
mcp-inspector-assess-cli https://my-mcp-server.example.com --transport http --method tools/list
|
|
935
960
|
|
|
936
961
|
# Connect to a remote MCP server (with custom headers)
|
|
937
|
-
|
|
962
|
+
mcp-inspector-assess-cli https://my-mcp-server.example.com --transport http --method tools/list --header "X-API-Key: your-api-key"
|
|
938
963
|
|
|
939
964
|
# Call a tool on a remote server
|
|
940
|
-
|
|
965
|
+
mcp-inspector-assess-cli https://my-mcp-server.example.com --method tools/call --tool-name remotetool --tool-arg param=value
|
|
941
966
|
|
|
942
967
|
# List resources from a remote server
|
|
943
|
-
|
|
968
|
+
mcp-inspector-assess-cli https://my-mcp-server.example.com --method resources/list
|
|
944
969
|
```
|
|
945
970
|
|
|
946
971
|
### UI Mode vs CLI Mode: When to Use Each
|
|
@@ -1037,6 +1062,16 @@ Please submit issues and pull requests to our repository: https://github.com/tri
|
|
|
1037
1062
|
|
|
1038
1063
|
This project builds upon the excellent foundation provided by Anthropic's MCP Inspector team. We're grateful for their work on the original inspector and the MCP protocol specification.
|
|
1039
1064
|
|
|
1065
|
+
## Links
|
|
1066
|
+
|
|
1067
|
+
- **npm Package**: https://www.npmjs.com/package/@bryan-thompson/inspector-assessment
|
|
1068
|
+
- **GitHub Repository**: https://github.com/triepod-ai/inspector-assessment
|
|
1069
|
+
- **Original MCP Inspector**: https://github.com/modelcontextprotocol/inspector
|
|
1070
|
+
- **Issues & Bug Reports**: https://github.com/triepod-ai/inspector-assessment/issues
|
|
1071
|
+
- **MCP Documentation**: https://modelcontextprotocol.io
|
|
1072
|
+
- **Publishing Guide**: [PUBLISHING_GUIDE.md](PUBLISHING_GUIDE.md)
|
|
1073
|
+
- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
|
|
1074
|
+
|
|
1040
1075
|
## License
|
|
1041
1076
|
|
|
1042
1077
|
This project is licensed under the MIT License—see the [LICENSE](LICENSE) file for details.
|
|
@@ -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-
|
|
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-DrU0QB6A.js";
|
|
2
2
|
const OAuthCallback = ({ onConnect }) => {
|
|
3
3
|
const { toast } = useToast();
|
|
4
4
|
const hasProcessedRef = reactExports.useRef(false);
|
package/client/dist/assets/{OAuthDebugCallback-B154gAVm.js → OAuthDebugCallback-Ca01948b.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-
|
|
1
|
+
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-DrU0QB6A.js";
|
|
2
2
|
const OAuthDebugCallback = ({ onConnect }) => {
|
|
3
3
|
reactExports.useEffect(() => {
|
|
4
4
|
let isProcessed = false;
|
|
@@ -16205,7 +16205,7 @@ objectType({
|
|
|
16205
16205
|
token_type_hint: stringType().optional()
|
|
16206
16206
|
}).strip();
|
|
16207
16207
|
const name = "@bryan-thompson/inspector-assessment-client";
|
|
16208
|
-
const version$1 = "1.
|
|
16208
|
+
const version$1 = "1.1.0";
|
|
16209
16209
|
const packageJson = {
|
|
16210
16210
|
name,
|
|
16211
16211
|
version: version$1
|
|
@@ -41736,7 +41736,7 @@ const useTheme = () => {
|
|
|
41736
41736
|
[theme, setThemeWithSideEffect]
|
|
41737
41737
|
);
|
|
41738
41738
|
};
|
|
41739
|
-
const version = "1.
|
|
41739
|
+
const version = "1.1.0";
|
|
41740
41740
|
var [createTooltipContext] = createContextScope("Tooltip", [
|
|
41741
41741
|
createPopperScope
|
|
41742
41742
|
]);
|
|
@@ -44133,6 +44133,8 @@ const ToolsTab = ({
|
|
|
44133
44133
|
const DEFAULT_ASSESSMENT_CONFIG = {
|
|
44134
44134
|
testTimeout: 3e4,
|
|
44135
44135
|
// 30 seconds per tool
|
|
44136
|
+
delayBetweenTests: 0,
|
|
44137
|
+
// No delay by default
|
|
44136
44138
|
skipBrokenTools: false,
|
|
44137
44139
|
reviewerMode: false,
|
|
44138
44140
|
enableExtendedAssessment: true,
|
|
@@ -44158,6 +44160,8 @@ const DEFAULT_ASSESSMENT_CONFIG = {
|
|
|
44158
44160
|
const REVIEWER_MODE_CONFIG = {
|
|
44159
44161
|
testTimeout: 1e4,
|
|
44160
44162
|
// 10 seconds per tool (faster)
|
|
44163
|
+
delayBetweenTests: 100,
|
|
44164
|
+
// Small delay for rate limiting
|
|
44161
44165
|
skipBrokenTools: true,
|
|
44162
44166
|
// Skip broken tools to save time
|
|
44163
44167
|
reviewerMode: true,
|
|
@@ -44188,6 +44192,8 @@ const REVIEWER_MODE_CONFIG = {
|
|
|
44188
44192
|
const DEVELOPER_MODE_CONFIG = {
|
|
44189
44193
|
testTimeout: 3e4,
|
|
44190
44194
|
// 30 seconds per tool
|
|
44195
|
+
delayBetweenTests: 500,
|
|
44196
|
+
// Moderate delay for thorough testing
|
|
44191
44197
|
skipBrokenTools: false,
|
|
44192
44198
|
reviewerMode: false,
|
|
44193
44199
|
enableExtendedAssessment: true,
|
|
@@ -44783,6 +44789,9 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44783
44789
|
);
|
|
44784
44790
|
testDetails.push(...toolTests);
|
|
44785
44791
|
passedTests += toolTests.filter((t) => t.passed).length;
|
|
44792
|
+
if (this.config.delayBetweenTests && this.config.delayBetweenTests > 0) {
|
|
44793
|
+
await this.sleep(this.config.delayBetweenTests);
|
|
44794
|
+
}
|
|
44786
44795
|
}
|
|
44787
44796
|
this.testCount = testDetails.length;
|
|
44788
44797
|
const metrics = this.calculateMetrics(testDetails, passedTests);
|
|
@@ -44837,7 +44846,7 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44837
44846
|
return tests;
|
|
44838
44847
|
}
|
|
44839
44848
|
async testMissingParameters(tool, callTool) {
|
|
44840
|
-
var _a;
|
|
44849
|
+
var _a, _b, _c;
|
|
44841
44850
|
const testInput = {};
|
|
44842
44851
|
const schema = this.getToolSchema(tool);
|
|
44843
44852
|
const hasRequiredParams = (schema == null ? void 0 : schema.required) && Array.isArray(schema.required) && schema.required.length > 0;
|
|
@@ -44883,9 +44892,9 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44883
44892
|
reason: isError ? void 0 : "Tool did not reject missing parameters"
|
|
44884
44893
|
};
|
|
44885
44894
|
} catch (error) {
|
|
44886
|
-
const
|
|
44887
|
-
const messageLower = (
|
|
44888
|
-
const isMeaningfulError = messageLower.includes("required") || messageLower.includes("missing") || messageLower.includes("parameter") || messageLower.includes("must") || messageLower.includes("invalid") || messageLower.includes("validation") || (
|
|
44895
|
+
const errorInfo = this.extractErrorInfo(error);
|
|
44896
|
+
const messageLower = ((_b = errorInfo.message) == null ? void 0 : _b.toLowerCase()) ?? "";
|
|
44897
|
+
const isMeaningfulError = messageLower.includes("required") || messageLower.includes("missing") || messageLower.includes("parameter") || messageLower.includes("must") || messageLower.includes("invalid") || messageLower.includes("validation") || (((_c = errorInfo.message) == null ? void 0 : _c.length) ?? 0) > 20;
|
|
44889
44898
|
return {
|
|
44890
44899
|
toolName: tool.name,
|
|
44891
44900
|
testType: "missing_required",
|
|
@@ -44893,7 +44902,8 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44893
44902
|
expectedError: "Missing required parameters",
|
|
44894
44903
|
actualResponse: {
|
|
44895
44904
|
isError: true,
|
|
44896
|
-
|
|
44905
|
+
errorCode: errorInfo.code,
|
|
44906
|
+
errorMessage: errorInfo.message,
|
|
44897
44907
|
rawResponse: error
|
|
44898
44908
|
},
|
|
44899
44909
|
passed: isMeaningfulError,
|
|
@@ -44902,7 +44912,7 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44902
44912
|
}
|
|
44903
44913
|
}
|
|
44904
44914
|
async testWrongTypes(tool, callTool) {
|
|
44905
|
-
var _a;
|
|
44915
|
+
var _a, _b, _c;
|
|
44906
44916
|
const schema = this.getToolSchema(tool);
|
|
44907
44917
|
const testInput = this.generateWrongTypeParams(schema);
|
|
44908
44918
|
try {
|
|
@@ -44932,9 +44942,9 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44932
44942
|
reason: isError ? void 0 : "Tool accepted wrong parameter types"
|
|
44933
44943
|
};
|
|
44934
44944
|
} catch (error) {
|
|
44935
|
-
const
|
|
44936
|
-
const messageLower = (
|
|
44937
|
-
const isMeaningfulError = messageLower.includes("type") || messageLower.includes("invalid") || messageLower.includes("expected") || messageLower.includes("must be") || messageLower.includes("validation") || messageLower.includes("string") || messageLower.includes("number") || (
|
|
44945
|
+
const errorInfo = this.extractErrorInfo(error);
|
|
44946
|
+
const messageLower = ((_b = errorInfo.message) == null ? void 0 : _b.toLowerCase()) ?? "";
|
|
44947
|
+
const isMeaningfulError = messageLower.includes("type") || messageLower.includes("invalid") || messageLower.includes("expected") || messageLower.includes("must be") || messageLower.includes("validation") || messageLower.includes("string") || messageLower.includes("number") || (((_c = errorInfo.message) == null ? void 0 : _c.length) ?? 0) > 20;
|
|
44938
44948
|
return {
|
|
44939
44949
|
toolName: tool.name,
|
|
44940
44950
|
testType: "wrong_type",
|
|
@@ -44942,7 +44952,8 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44942
44952
|
expectedError: "Type validation error",
|
|
44943
44953
|
actualResponse: {
|
|
44944
44954
|
isError: true,
|
|
44945
|
-
|
|
44955
|
+
errorCode: errorInfo.code,
|
|
44956
|
+
errorMessage: errorInfo.message,
|
|
44946
44957
|
rawResponse: error
|
|
44947
44958
|
},
|
|
44948
44959
|
passed: isMeaningfulError,
|
|
@@ -44951,6 +44962,7 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44951
44962
|
}
|
|
44952
44963
|
}
|
|
44953
44964
|
async testInvalidValues(tool, callTool) {
|
|
44965
|
+
var _a, _b;
|
|
44954
44966
|
const schema = this.getToolSchema(tool);
|
|
44955
44967
|
const testInput = this.generateInvalidValueParams(schema);
|
|
44956
44968
|
try {
|
|
@@ -44975,9 +44987,9 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44975
44987
|
reason: isError ? void 0 : "Tool accepted invalid values"
|
|
44976
44988
|
};
|
|
44977
44989
|
} catch (error) {
|
|
44978
|
-
const
|
|
44979
|
-
const messageLower = (
|
|
44980
|
-
const isMeaningfulError = messageLower.includes("invalid") || messageLower.includes("not allowed") || messageLower.includes("must") || messageLower.includes("cannot") || messageLower.includes("validation") || messageLower.includes("error") || (
|
|
44990
|
+
const errorInfo = this.extractErrorInfo(error);
|
|
44991
|
+
const messageLower = ((_a = errorInfo.message) == null ? void 0 : _a.toLowerCase()) ?? "";
|
|
44992
|
+
const isMeaningfulError = messageLower.includes("invalid") || messageLower.includes("not allowed") || messageLower.includes("must") || messageLower.includes("cannot") || messageLower.includes("validation") || messageLower.includes("error") || (((_b = errorInfo.message) == null ? void 0 : _b.length) ?? 0) > 15;
|
|
44981
44993
|
return {
|
|
44982
44994
|
toolName: tool.name,
|
|
44983
44995
|
testType: "invalid_values",
|
|
@@ -44985,7 +44997,8 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44985
44997
|
expectedError: "Invalid parameter values",
|
|
44986
44998
|
actualResponse: {
|
|
44987
44999
|
isError: true,
|
|
44988
|
-
|
|
45000
|
+
errorCode: errorInfo.code,
|
|
45001
|
+
errorMessage: errorInfo.message,
|
|
44989
45002
|
rawResponse: error
|
|
44990
45003
|
},
|
|
44991
45004
|
passed: isMeaningfulError,
|
|
@@ -44994,6 +45007,7 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
44994
45007
|
}
|
|
44995
45008
|
}
|
|
44996
45009
|
async testExcessiveInput(tool, callTool) {
|
|
45010
|
+
var _a, _b;
|
|
44997
45011
|
const largeString = "x".repeat(1e5);
|
|
44998
45012
|
const testInput = this.generateParamsWithValue(tool, largeString);
|
|
44999
45013
|
try {
|
|
@@ -45020,9 +45034,9 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
45020
45034
|
reason: !isError && !response ? "Tool crashed on large input" : void 0
|
|
45021
45035
|
};
|
|
45022
45036
|
} catch (error) {
|
|
45023
|
-
const
|
|
45024
|
-
const messageLower = (
|
|
45025
|
-
const isMeaningfulError = messageLower.includes("size") || messageLower.includes("large") || messageLower.includes("limit") || messageLower.includes("exceed") || messageLower.includes("too") || messageLower.includes("maximum") || (
|
|
45037
|
+
const errorInfo = this.extractErrorInfo(error);
|
|
45038
|
+
const messageLower = ((_a = errorInfo.message) == null ? void 0 : _a.toLowerCase()) ?? "";
|
|
45039
|
+
const isMeaningfulError = messageLower.includes("size") || messageLower.includes("large") || messageLower.includes("limit") || messageLower.includes("exceed") || messageLower.includes("too") || messageLower.includes("maximum") || (((_b = errorInfo.message) == null ? void 0 : _b.length) ?? 0) > 10;
|
|
45026
45040
|
return {
|
|
45027
45041
|
toolName: tool.name,
|
|
45028
45042
|
testType: "excessive_input",
|
|
@@ -45030,7 +45044,8 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
45030
45044
|
expectedError: "Input size limit exceeded",
|
|
45031
45045
|
actualResponse: {
|
|
45032
45046
|
isError: true,
|
|
45033
|
-
|
|
45047
|
+
errorCode: errorInfo.code,
|
|
45048
|
+
errorMessage: errorInfo.message,
|
|
45034
45049
|
rawResponse: "[error details omitted]"
|
|
45035
45050
|
},
|
|
45036
45051
|
passed: isMeaningfulError,
|
|
@@ -45178,12 +45193,17 @@ class ErrorHandlingAssessor extends BaseAssessor {
|
|
|
45178
45193
|
else if (score >= 70) quality = "good";
|
|
45179
45194
|
else if (score >= 50) quality = "fair";
|
|
45180
45195
|
else quality = "poor";
|
|
45181
|
-
const
|
|
45196
|
+
const actualErrors = tests.filter((t) => t.actualResponse.isError);
|
|
45197
|
+
const errorsWithCodes = actualErrors.filter(
|
|
45182
45198
|
(t) => t.actualResponse.errorCode !== void 0
|
|
45183
|
-
);
|
|
45184
|
-
const
|
|
45199
|
+
).length;
|
|
45200
|
+
const errorsWithMessages = actualErrors.filter(
|
|
45185
45201
|
(t) => t.actualResponse.errorMessage && t.actualResponse.errorMessage.length > 10
|
|
45186
|
-
);
|
|
45202
|
+
).length;
|
|
45203
|
+
const hasProperErrorCodes = actualErrors.length === 0 || // If no errors were triggered, we can't assess this
|
|
45204
|
+
errorsWithCodes / actualErrors.length >= 0.5;
|
|
45205
|
+
const hasDescriptiveMessages = actualErrors.length === 0 || // If no errors were triggered, we can't assess this
|
|
45206
|
+
errorsWithMessages / actualErrors.length >= 0.5;
|
|
45187
45207
|
const validatesInputs = tests.filter((t) => ["missing_required", "wrong_type"].includes(t.testType)).some((t) => t.passed);
|
|
45188
45208
|
return {
|
|
45189
45209
|
mcpComplianceScore: score,
|
|
@@ -48008,9 +48028,17 @@ class ResponseValidator {
|
|
|
48008
48028
|
}
|
|
48009
48029
|
}
|
|
48010
48030
|
class TestScenarioEngine {
|
|
48011
|
-
constructor(testTimeout = 5e3) {
|
|
48031
|
+
constructor(testTimeout = 5e3, delayBetweenTests = 0) {
|
|
48012
48032
|
__publicField(this, "testTimeout");
|
|
48033
|
+
__publicField(this, "delayBetweenTests");
|
|
48013
48034
|
this.testTimeout = testTimeout;
|
|
48035
|
+
this.delayBetweenTests = delayBetweenTests;
|
|
48036
|
+
}
|
|
48037
|
+
/**
|
|
48038
|
+
* Sleep for specified milliseconds (for rate limiting)
|
|
48039
|
+
*/
|
|
48040
|
+
async sleep(ms) {
|
|
48041
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
48014
48042
|
}
|
|
48015
48043
|
/**
|
|
48016
48044
|
* Test tool with progressive complexity to identify failure points
|
|
@@ -48163,6 +48191,9 @@ class TestScenarioEngine {
|
|
|
48163
48191
|
callTool
|
|
48164
48192
|
);
|
|
48165
48193
|
result.scenarioResults.push(scenarioResult);
|
|
48194
|
+
if (this.delayBetweenTests > 0) {
|
|
48195
|
+
await this.sleep(this.delayBetweenTests);
|
|
48196
|
+
}
|
|
48166
48197
|
if (scenarioResult.executed) {
|
|
48167
48198
|
result.scenariosExecuted++;
|
|
48168
48199
|
if (scenarioResult.validation.isValid) {
|
|
@@ -48573,7 +48604,10 @@ class MCPAssessmentService {
|
|
|
48573
48604
|
* Enhanced functionality assessment with multi-scenario testing
|
|
48574
48605
|
*/
|
|
48575
48606
|
async assessFunctionalityEnhanced(tools, callTool) {
|
|
48576
|
-
const engine = new TestScenarioEngine(
|
|
48607
|
+
const engine = new TestScenarioEngine(
|
|
48608
|
+
this.config.testTimeout,
|
|
48609
|
+
this.config.delayBetweenTests ?? 0
|
|
48610
|
+
);
|
|
48577
48611
|
const toolResults = [];
|
|
48578
48612
|
const enhancedResults = [];
|
|
48579
48613
|
let workingCount = 0;
|
|
@@ -50718,6 +50752,30 @@ const AssessmentTab = ({
|
|
|
50718
50752
|
),
|
|
50719
50753
|
!isLoadingTools && tools.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Select which tools to test for error handling (the most intensive tests). All tools are selected by default." })
|
|
50720
50754
|
] }),
|
|
50755
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
50756
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Label$1, { htmlFor: "delay-between-tests", children: "Delay between tests (milliseconds)" }),
|
|
50757
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50758
|
+
Input,
|
|
50759
|
+
{
|
|
50760
|
+
id: "delay-between-tests",
|
|
50761
|
+
type: "number",
|
|
50762
|
+
min: "0",
|
|
50763
|
+
max: "5000",
|
|
50764
|
+
step: "100",
|
|
50765
|
+
value: config.delayBetweenTests ?? 0,
|
|
50766
|
+
onChange: (e) => {
|
|
50767
|
+
const value = parseInt(e.target.value, 10);
|
|
50768
|
+
setConfig({
|
|
50769
|
+
...config,
|
|
50770
|
+
delayBetweenTests: isNaN(value) ? 0 : value
|
|
50771
|
+
});
|
|
50772
|
+
},
|
|
50773
|
+
disabled: isRunning,
|
|
50774
|
+
placeholder: "0"
|
|
50775
|
+
}
|
|
50776
|
+
),
|
|
50777
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Add a delay between tests to avoid rate limiting. Recommended: 500-1000ms for rate-limited APIs. Set to 0 for no delay (default)." })
|
|
50778
|
+
] }),
|
|
50721
50779
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2 border rounded-lg p-4 bg-blue-50 dark:bg-blue-950", children: [
|
|
50722
50780
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
50723
50781
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -50734,15 +50792,15 @@ const AssessmentTab = ({
|
|
|
50734
50792
|
),
|
|
50735
50793
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Label$1, { htmlFor: "domain-testing", className: "cursor-pointer", children: [
|
|
50736
50794
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: "Enable Advanced Security Testing" }),
|
|
50737
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-0.5 rounded", children: "18
|
|
50795
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-0.5 rounded", children: "18 Patterns" })
|
|
50738
50796
|
] })
|
|
50739
50797
|
] }),
|
|
50740
50798
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground ml-6", children: [
|
|
50741
50799
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Basic:" }),
|
|
50742
|
-
" 3
|
|
50800
|
+
" 3 common patterns (~48 checks).",
|
|
50743
50801
|
" ",
|
|
50744
50802
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Advanced:" }),
|
|
50745
|
-
" All 18 patterns.
|
|
50803
|
+
" All 18 patterns. Designed to identify potential issues like Direct Command Injection, Role Override, Data Exfiltration, System Commands, Tool Shadowing, Context Escape, and 12+ other common attack vectors."
|
|
50746
50804
|
] })
|
|
50747
50805
|
] }),
|
|
50748
50806
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
@@ -51857,7 +51915,8 @@ const ErrorTestItem = ({ test }) => {
|
|
|
51857
51915
|
{
|
|
51858
51916
|
className: "text-xs border-l-2 pl-3 py-1",
|
|
51859
51917
|
style: {
|
|
51860
|
-
borderColor: test.passed ? "rgb(34 197 94)" : "rgb(239 68 68)"
|
|
51918
|
+
borderColor: test.testType === "invalid_values" ? "rgb(234 179 8)" : test.passed ? "rgb(34 197 94)" : "rgb(239 68 68)"
|
|
51919
|
+
// red-500 for FAIL
|
|
51861
51920
|
},
|
|
51862
51921
|
children: [
|
|
51863
51922
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -53106,13 +53165,13 @@ const App = () => {
|
|
|
53106
53165
|
) });
|
|
53107
53166
|
if (window.location.pathname === "/oauth/callback") {
|
|
53108
53167
|
const OAuthCallback = React.lazy(
|
|
53109
|
-
() => __vitePreload(() => import("./OAuthCallback-
|
|
53168
|
+
() => __vitePreload(() => import("./OAuthCallback-aV2t2Zmo.js"), true ? [] : void 0)
|
|
53110
53169
|
);
|
|
53111
53170
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
|
|
53112
53171
|
}
|
|
53113
53172
|
if (window.location.pathname === "/oauth/callback/debug") {
|
|
53114
53173
|
const OAuthDebugCallback = React.lazy(
|
|
53115
|
-
() => __vitePreload(() => import("./OAuthDebugCallback-
|
|
53174
|
+
() => __vitePreload(() => import("./OAuthDebugCallback-Ca01948b.js"), true ? [] : void 0)
|
|
53116
53175
|
);
|
|
53117
53176
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
|
|
53118
53177
|
}
|
package/client/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
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-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DrU0QB6A.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-DYiWOife.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
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>",
|
package/server/build/index.js
CHANGED
|
File without changes
|