@bryan-thompson/inspector-assessment-client 1.22.3 → 1.22.5
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/dist/assets/{OAuthCallback-BVO57XO6.js → OAuthCallback-B5zTjfUQ.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-Dou7_Gex.js → OAuthDebugCallback-NE-WvEWH.js} +1 -1
- package/dist/assets/{index-DdB_RMJV.js → index-DILbEAS1.js} +4 -4
- package/dist/index.html +1 -1
- package/lib/services/assessment/modules/ToolAnnotationAssessor.d.ts +1 -0
- package/lib/services/assessment/modules/ToolAnnotationAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/ToolAnnotationAssessor.js +158 -27
- package/package.json +1 -1
|
@@ -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-DILbEAS1.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-
|
|
1
|
+
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-DILbEAS1.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.22.
|
|
16323
|
+
const version$1 = "1.22.5";
|
|
16324
16324
|
const packageJson = {
|
|
16325
16325
|
name,
|
|
16326
16326
|
version: version$1
|
|
@@ -45352,7 +45352,7 @@ const useTheme = () => {
|
|
|
45352
45352
|
[theme, setThemeWithSideEffect]
|
|
45353
45353
|
);
|
|
45354
45354
|
};
|
|
45355
|
-
const version = "1.22.
|
|
45355
|
+
const version = "1.22.5";
|
|
45356
45356
|
var [createTooltipContext] = createContextScope("Tooltip", [
|
|
45357
45357
|
createPopperScope
|
|
45358
45358
|
]);
|
|
@@ -59266,13 +59266,13 @@ const App = () => {
|
|
|
59266
59266
|
) });
|
|
59267
59267
|
if (window.location.pathname === "/oauth/callback") {
|
|
59268
59268
|
const OAuthCallback = React.lazy(
|
|
59269
|
-
() => __vitePreload(() => import("./OAuthCallback-
|
|
59269
|
+
() => __vitePreload(() => import("./OAuthCallback-B5zTjfUQ.js"), true ? [] : void 0)
|
|
59270
59270
|
);
|
|
59271
59271
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
|
|
59272
59272
|
}
|
|
59273
59273
|
if (window.location.pathname === "/oauth/callback/debug") {
|
|
59274
59274
|
const OAuthDebugCallback = React.lazy(
|
|
59275
|
-
() => __vitePreload(() => import("./OAuthDebugCallback-
|
|
59275
|
+
() => __vitePreload(() => import("./OAuthDebugCallback-NE-WvEWH.js"), true ? [] : void 0)
|
|
59276
59276
|
);
|
|
59277
59277
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
|
|
59278
59278
|
}
|
package/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-DILbEAS1.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-DiyPO_Zj.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
@@ -82,6 +82,7 @@ export declare class ToolAnnotationAssessor extends BaseAssessor {
|
|
|
82
82
|
/**
|
|
83
83
|
* Assess a single tool's annotations
|
|
84
84
|
* Now includes alignment status with confidence-aware logic
|
|
85
|
+
* Enhanced with high-confidence deception detection for obvious misalignments
|
|
85
86
|
*/
|
|
86
87
|
private assessTool;
|
|
87
88
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolAnnotationAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/ToolAnnotationAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EACV,wBAAwB,EACxB,oBAAoB,EAKpB,uBAAuB,EAExB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAK9B,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"ToolAnnotationAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/ToolAnnotationAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EACV,wBAAwB,EACxB,oBAAoB,EAKpB,uBAAuB,EAExB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAK9B,MAAM,8BAA8B,CAAC;AAyXtC;;GAEG;AACH,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,eAAe,CAAC,EAAE;QAChB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,oBAAoB,EAAE;YACpB,YAAY,CAAC,EAAE,OAAO,CAAC;YACvB,eAAe,CAAC,EAAE,OAAO,CAAC;YAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;SAC1B,CAAC;QACF,oBAAoB,EAAE,OAAO,CAAC;QAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,MAAM,EAAE,iBAAiB,GAAG,eAAe,CAAC;KAC7C,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gCAAiC,SAAQ,wBAAwB;IAChF,WAAW,EAAE,4BAA4B,EAAE,CAAC;IAC5C,cAAc,EAAE,OAAO,CAAC;IACxB,2BAA2B,EAAE,4BAA4B,EAAE,CAAC;CAC7D;AAKD,qBAAa,sBAAuB,SAAQ,YAAY;IACtD,OAAO,CAAC,YAAY,CAAC,CAAmB;IACxC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,kBAAkB,CAAC,CAA2B;gBAE1C,MAAM,EAAE,uBAAuB;IAM3C;;OAEG;IACH,qBAAqB,IAAI,wBAAwB,GAAG,SAAS;IAI7D;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAK7C;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAK/C;;OAEG;IACH,eAAe,IAAI,OAAO;IAO1B;;OAEG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,wBAAwB,GAAG,gCAAgC,CAAC;IAmUvE;;OAEG;YACW,0BAA0B;IA+IxC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAiCnC;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAoFvC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA0IlB;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IA2DnC;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB;IAyE1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAmKrB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IA0DjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiDxB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmC3B;;OAEG;IACH,OAAO,CAAC,uBAAuB;CA2ChC"}
|
|
@@ -12,6 +12,115 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { BaseAssessor } from "./BaseAssessor.js";
|
|
14
14
|
import { getDefaultCompiledPatterns, matchToolPattern, detectPersistenceModel, checkDescriptionForImmediatePersistence, } from "../config/annotationPatterns.js";
|
|
15
|
+
/**
|
|
16
|
+
* High-confidence deception detection patterns
|
|
17
|
+
* These patterns detect obvious misalignment between annotations and tool names
|
|
18
|
+
* where keywords appear ANYWHERE in the tool name (not just as prefixes)
|
|
19
|
+
*/
|
|
20
|
+
/** Keywords that contradict readOnlyHint=true (these tools modify state) */
|
|
21
|
+
const READONLY_CONTRADICTION_KEYWORDS = [
|
|
22
|
+
// Execution keywords - tools that execute code/commands are never read-only
|
|
23
|
+
"exec",
|
|
24
|
+
"execute",
|
|
25
|
+
"run",
|
|
26
|
+
"shell",
|
|
27
|
+
"command",
|
|
28
|
+
"cmd",
|
|
29
|
+
"spawn",
|
|
30
|
+
"invoke",
|
|
31
|
+
// Write/modify keywords
|
|
32
|
+
"write",
|
|
33
|
+
"create",
|
|
34
|
+
"delete",
|
|
35
|
+
"remove",
|
|
36
|
+
"modify",
|
|
37
|
+
"update",
|
|
38
|
+
"edit",
|
|
39
|
+
"change",
|
|
40
|
+
"set",
|
|
41
|
+
"put",
|
|
42
|
+
"patch",
|
|
43
|
+
// Deployment/installation keywords
|
|
44
|
+
"install",
|
|
45
|
+
"deploy",
|
|
46
|
+
"upload",
|
|
47
|
+
"push",
|
|
48
|
+
// Communication keywords (sending data)
|
|
49
|
+
"send",
|
|
50
|
+
"post",
|
|
51
|
+
"submit",
|
|
52
|
+
"publish",
|
|
53
|
+
// Destructive keywords
|
|
54
|
+
"destroy",
|
|
55
|
+
"drop",
|
|
56
|
+
"purge",
|
|
57
|
+
"wipe",
|
|
58
|
+
"clear",
|
|
59
|
+
"truncate",
|
|
60
|
+
"reset",
|
|
61
|
+
"kill",
|
|
62
|
+
"terminate",
|
|
63
|
+
];
|
|
64
|
+
/** Keywords that contradict destructiveHint=false (these tools delete/destroy data) */
|
|
65
|
+
const DESTRUCTIVE_CONTRADICTION_KEYWORDS = [
|
|
66
|
+
"delete",
|
|
67
|
+
"remove",
|
|
68
|
+
"drop",
|
|
69
|
+
"destroy",
|
|
70
|
+
"purge",
|
|
71
|
+
"wipe",
|
|
72
|
+
"erase",
|
|
73
|
+
"truncate",
|
|
74
|
+
"clear",
|
|
75
|
+
"reset",
|
|
76
|
+
"kill",
|
|
77
|
+
"terminate",
|
|
78
|
+
"revoke",
|
|
79
|
+
"cancel",
|
|
80
|
+
"force",
|
|
81
|
+
];
|
|
82
|
+
/**
|
|
83
|
+
* Check if a tool name contains any of the given keywords (case-insensitive)
|
|
84
|
+
* Looks for keywords anywhere in the name, not just as prefixes
|
|
85
|
+
*/
|
|
86
|
+
function containsKeyword(toolName, keywords) {
|
|
87
|
+
const lowerName = toolName.toLowerCase();
|
|
88
|
+
for (const keyword of keywords) {
|
|
89
|
+
if (lowerName.includes(keyword)) {
|
|
90
|
+
return keyword;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Detect high-confidence annotation deception
|
|
97
|
+
* Returns misalignment info if obvious deception detected, null otherwise
|
|
98
|
+
*/
|
|
99
|
+
function detectAnnotationDeception(toolName, annotations) {
|
|
100
|
+
// Check readOnlyHint=true contradiction
|
|
101
|
+
if (annotations.readOnlyHint === true) {
|
|
102
|
+
const keyword = containsKeyword(toolName, READONLY_CONTRADICTION_KEYWORDS);
|
|
103
|
+
if (keyword) {
|
|
104
|
+
return {
|
|
105
|
+
field: "readOnlyHint",
|
|
106
|
+
matchedKeyword: keyword,
|
|
107
|
+
reason: `Tool name contains '${keyword}' but claims readOnlyHint=true - this is likely deceptive`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Check destructiveHint=false contradiction
|
|
112
|
+
if (annotations.destructiveHint === false) {
|
|
113
|
+
const keyword = containsKeyword(toolName, DESTRUCTIVE_CONTRADICTION_KEYWORDS);
|
|
114
|
+
if (keyword) {
|
|
115
|
+
return {
|
|
116
|
+
field: "destructiveHint",
|
|
117
|
+
matchedKeyword: keyword,
|
|
118
|
+
reason: `Tool name contains '${keyword}' but claims destructiveHint=false - this is likely deceptive`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
15
124
|
const DESCRIPTION_POISONING_PATTERNS = [
|
|
16
125
|
// Hidden instruction tags
|
|
17
126
|
{
|
|
@@ -726,6 +835,7 @@ export class ToolAnnotationAssessor extends BaseAssessor {
|
|
|
726
835
|
/**
|
|
727
836
|
* Assess a single tool's annotations
|
|
728
837
|
* Now includes alignment status with confidence-aware logic
|
|
838
|
+
* Enhanced with high-confidence deception detection for obvious misalignments
|
|
729
839
|
*/
|
|
730
840
|
assessTool(tool) {
|
|
731
841
|
const issues = [];
|
|
@@ -745,36 +855,57 @@ export class ToolAnnotationAssessor extends BaseAssessor {
|
|
|
745
855
|
alignmentStatus = "UNKNOWN";
|
|
746
856
|
}
|
|
747
857
|
else {
|
|
748
|
-
// Check for
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
annotations.destructiveHint
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
}
|
|
858
|
+
// FIRST: Check for high-confidence deception (keywords anywhere in tool name)
|
|
859
|
+
// This catches obvious cases like "vulnerable_system_exec_tool" + readOnlyHint=true
|
|
860
|
+
const deception = detectAnnotationDeception(tool.name, {
|
|
861
|
+
readOnlyHint: annotations.readOnlyHint,
|
|
862
|
+
destructiveHint: annotations.destructiveHint,
|
|
863
|
+
});
|
|
864
|
+
if (deception) {
|
|
865
|
+
// High-confidence deception detected - this is MISALIGNED, not REVIEW_RECOMMENDED
|
|
866
|
+
alignmentStatus = "MISALIGNED";
|
|
867
|
+
issues.push(`DECEPTIVE ANNOTATION: ${deception.reason}`);
|
|
868
|
+
recommendations.push(`CRITICAL: Fix deceptive ${deception.field} for ${tool.name} - tool name contains '${deception.matchedKeyword}' which contradicts the annotation`);
|
|
869
|
+
// Override inferred behavior to match the detected deception
|
|
870
|
+
if (deception.field === "readOnlyHint") {
|
|
871
|
+
inferredBehavior.expectedReadOnly = false;
|
|
872
|
+
inferredBehavior.confidence = "high";
|
|
873
|
+
inferredBehavior.isAmbiguous = false;
|
|
874
|
+
inferredBehavior.reason = deception.reason;
|
|
766
875
|
}
|
|
767
876
|
else {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
877
|
+
inferredBehavior.expectedDestructive = true;
|
|
878
|
+
inferredBehavior.confidence = "high";
|
|
879
|
+
inferredBehavior.isAmbiguous = false;
|
|
880
|
+
inferredBehavior.reason = deception.reason;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
// Normal flow: Check for misaligned annotations with confidence-aware logic
|
|
885
|
+
const readOnlyMismatch = annotations.readOnlyHint !== undefined &&
|
|
886
|
+
annotations.readOnlyHint !== inferredBehavior.expectedReadOnly;
|
|
887
|
+
const destructiveMismatch = annotations.destructiveHint !== undefined &&
|
|
888
|
+
annotations.destructiveHint !== inferredBehavior.expectedDestructive;
|
|
889
|
+
if (readOnlyMismatch || destructiveMismatch) {
|
|
890
|
+
// Only flag misalignment for medium/high confidence inference
|
|
891
|
+
// When confidence is low/ambiguous, trust the explicit annotation
|
|
892
|
+
// Note: High-confidence deception detection (exec/install keywords)
|
|
893
|
+
// is handled in the `deception` block above, not here
|
|
894
|
+
if (!inferredBehavior.isAmbiguous &&
|
|
895
|
+
inferredBehavior.confidence !== "low") {
|
|
896
|
+
// Medium/high confidence mismatch: MISALIGNED
|
|
897
|
+
alignmentStatus = "MISALIGNED";
|
|
898
|
+
if (readOnlyMismatch) {
|
|
899
|
+
issues.push(`Potentially misaligned readOnlyHint: set to ${annotations.readOnlyHint}, expected ${inferredBehavior.expectedReadOnly} based on tool name pattern`);
|
|
900
|
+
recommendations.push(`Verify readOnlyHint for ${tool.name}: currently ${annotations.readOnlyHint}, tool name suggests ${inferredBehavior.expectedReadOnly}`);
|
|
901
|
+
}
|
|
902
|
+
if (destructiveMismatch) {
|
|
903
|
+
issues.push(`Potentially misaligned destructiveHint: set to ${annotations.destructiveHint}, expected ${inferredBehavior.expectedDestructive} based on tool name pattern`);
|
|
904
|
+
recommendations.push(`Verify destructiveHint for ${tool.name}: currently ${annotations.destructiveHint}, tool name suggests ${inferredBehavior.expectedDestructive}`);
|
|
905
|
+
}
|
|
777
906
|
}
|
|
907
|
+
// When inference is ambiguous/low confidence, trust the explicit annotation
|
|
908
|
+
// and keep alignmentStatus as ALIGNED (no change needed)
|
|
778
909
|
}
|
|
779
910
|
}
|
|
780
911
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment-client",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.5",
|
|
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>",
|