@modelcontextprotocol/inspector 2.14.0 → 2.15.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/clients/cli/build/index.js +4906 -2205
- package/clients/mcpdo/build/mcp-bin.js +891 -180
- package/clients/mcpdo/build/mcpdod.js +2 -3
- package/clients/mcpdo/build/{server-Dv339Ejx.js → server-B-CUVIBj.js} +2750 -1039
- package/clients/tui/build/index.js +1354 -533
- package/clients/web/build/index.js +239 -159
- package/clients/web/dist/assets/index-BZ94R6fh.js +1599 -0
- package/clients/web/dist/assets/{index-Dval2a7I.css → index-tBehH5iF.css} +1 -1
- package/clients/web/dist/assets/{prism-light-CoVRM9R2.js → prism-light-Crps--E8.js} +1 -1
- package/clients/web/dist/assets/worker-json-DEGsizKa.js +7859 -0
- package/clients/web/dist/index.html +2 -2
- package/package.json +4 -1
- package/skills/mcpdo/SKILL.md +50 -3
- package/clients/web/dist/assets/index-BCud2uMC.js +0 -1594
- package/clients/web/dist/assets/worker-json-8CDXFfik.js +0 -1631
|
@@ -43,15 +43,14 @@ import os from "node:os";
|
|
|
43
43
|
import process$1 from "node:process";
|
|
44
44
|
import tty from "node:tty";
|
|
45
45
|
import { isDeepStrictEqual } from "node:util";
|
|
46
|
-
|
|
46
|
+
// ../../core/storage/store-serialize.ts
|
|
47
47
|
function serializeStore(data) {
|
|
48
48
|
return JSON.stringify(data, null, 2);
|
|
49
49
|
}
|
|
50
50
|
function parseStore(raw) {
|
|
51
51
|
return JSON.parse(raw);
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
//#region ../../core/storage/store-io.ts
|
|
53
|
+
// ../../core/storage/store-io.ts
|
|
55
54
|
function getDefaultStorageDir() {
|
|
56
55
|
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
|
57
56
|
return path$1.join(homeDir, ".mcp-inspector", "storage");
|
|
@@ -97,8 +96,7 @@ async function deleteStoreFile(filePath) {
|
|
|
97
96
|
if (error.code !== "ENOENT") throw error;
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
|
-
|
|
101
|
-
//#region ../../core/mcp/types.ts
|
|
99
|
+
// ../../core/mcp/types.ts
|
|
102
100
|
function isTerminalStatus(status) {
|
|
103
101
|
return status === "disconnected" || status === "error";
|
|
104
102
|
}
|
|
@@ -136,8 +134,7 @@ function eraToVersionNegotiation(era) {
|
|
|
136
134
|
case "legacy": return { mode: "legacy" };
|
|
137
135
|
}
|
|
138
136
|
}
|
|
139
|
-
|
|
140
|
-
//#region ../../core/extension/skills/schemas.ts
|
|
137
|
+
// ../../core/extension/skills/schemas.ts
|
|
141
138
|
const CACHE_FIELDS = {
|
|
142
139
|
ttlMs: ReadResourceDirectoryResultSchema.shape.ttlMs,
|
|
143
140
|
cacheScope: SkillCacheScopeSchema
|
|
@@ -170,8 +167,7 @@ const DirectoryReadResultSchema = ReadResourceDirectoryResultSchema.partial({
|
|
|
170
167
|
ttlMs: true,
|
|
171
168
|
cacheScope: true
|
|
172
169
|
});
|
|
173
|
-
|
|
174
|
-
//#region ../../core/extension/skills/sha256.ts
|
|
170
|
+
// ../../core/extension/skills/sha256.ts
|
|
175
171
|
const K = new Uint32Array([
|
|
176
172
|
1116352408,
|
|
177
173
|
1899447441,
|
|
@@ -297,8 +293,7 @@ function sha256Bytes(bytes) {
|
|
|
297
293
|
for (let i = 0; i < 8; i += 1) out.setUint32(i * 4, h[i]);
|
|
298
294
|
return digest;
|
|
299
295
|
}
|
|
300
|
-
|
|
301
|
-
//#region ../../core/extension/skills/skillFile.ts
|
|
296
|
+
// ../../core/extension/skills/skillFile.ts
|
|
302
297
|
function splitSkillFile(text) {
|
|
303
298
|
if (!/^---[ \t]*\r?\n/.test(text)) return { body: text };
|
|
304
299
|
const rest = text.slice(text.indexOf("\n") + 1);
|
|
@@ -346,8 +341,7 @@ function parseSkillFrontmatter(yamlText) {
|
|
|
346
341
|
if (graphError) return { error: graphError };
|
|
347
342
|
return { fields: parsed };
|
|
348
343
|
}
|
|
349
|
-
|
|
350
|
-
//#region ../../core/extension/skills/conformance.ts
|
|
344
|
+
// ../../core/extension/skills/conformance.ts
|
|
351
345
|
const SKILL_MAX_RESOURCE_ENTRIES = SKILL_LIMITS.files;
|
|
352
346
|
const SKILL_MAX_TOTAL_BYTES = SKILL_LIMITS.bytes;
|
|
353
347
|
const SKILL_MAX_CATALOG_BYTES = 67108864;
|
|
@@ -705,13 +699,11 @@ function checkSkillNameCollisions(entries) {
|
|
|
705
699
|
}
|
|
706
700
|
return issues;
|
|
707
701
|
}
|
|
708
|
-
|
|
709
|
-
//#region ../../core/auth/secret-fields.ts
|
|
702
|
+
// ../../core/auth/secret-fields.ts
|
|
710
703
|
const SECRET_FIELD_OAUTH_CLIENT_SECRET = "oauth-client-secret";
|
|
711
704
|
const SECRET_FIELD_IDP_CLIENT_SECRET = "idp-client-secret";
|
|
712
705
|
const envSecretField = (envKey) => `env:${envKey}`;
|
|
713
|
-
|
|
714
|
-
//#region ../../core/json/localRefs.ts
|
|
706
|
+
// ../../core/json/localRefs.ts
|
|
715
707
|
const SUBSCHEMA_KEYWORDS$1 = /* @__PURE__ */ new Set([
|
|
716
708
|
"items",
|
|
717
709
|
"contains",
|
|
@@ -866,8 +858,7 @@ function inlineLocalRefs(schema) {
|
|
|
866
858
|
cache.set(schema, resolved);
|
|
867
859
|
return resolved;
|
|
868
860
|
}
|
|
869
|
-
|
|
870
|
-
//#region ../../core/json/nullableUnion.ts
|
|
861
|
+
// ../../core/json/nullableUnion.ts
|
|
871
862
|
const RENDERABLE_TYPES = [
|
|
872
863
|
"string",
|
|
873
864
|
"number",
|
|
@@ -1020,8 +1011,7 @@ function normalizeNullableUnion(schema) {
|
|
|
1020
1011
|
}
|
|
1021
1012
|
return schema;
|
|
1022
1013
|
}
|
|
1023
|
-
|
|
1024
|
-
//#region ../../core/json/rootUnion.ts
|
|
1014
|
+
// ../../core/json/rootUnion.ts
|
|
1025
1015
|
function membersOf(value) {
|
|
1026
1016
|
return Array.isArray(value) ? value : [];
|
|
1027
1017
|
}
|
|
@@ -1241,8 +1231,7 @@ function narrowBySuppliedNames(branches, candidates, suppliedNames) {
|
|
|
1241
1231
|
const named = new Set(suppliedNames.map((name) => exclusiveTo.get(name)).filter((index) => index !== void 0 && index >= 0));
|
|
1242
1232
|
return named.size === 1 ? [...named][0] : null;
|
|
1243
1233
|
}
|
|
1244
|
-
|
|
1245
|
-
//#region ../../core/json/jsonUtils.ts
|
|
1234
|
+
// ../../core/json/jsonUtils.ts
|
|
1246
1235
|
function isSerializableJson(value) {
|
|
1247
1236
|
if (value === null) return true;
|
|
1248
1237
|
switch (typeof value) {
|
|
@@ -1343,8 +1332,7 @@ function convertPromptArguments(args) {
|
|
|
1343
1332
|
else stringArgs[key] = JSON.stringify(value);
|
|
1344
1333
|
return stringArgs;
|
|
1345
1334
|
}
|
|
1346
|
-
|
|
1347
|
-
//#region ../../core/mcp/serverList.ts
|
|
1335
|
+
// ../../core/mcp/serverList.ts
|
|
1348
1336
|
const VALID_SERVER_TYPES = /* @__PURE__ */ new Set([
|
|
1349
1337
|
"stdio",
|
|
1350
1338
|
"sse",
|
|
@@ -1618,8 +1606,7 @@ function adHocServerName(config) {
|
|
|
1618
1606
|
}
|
|
1619
1607
|
return config.command?.split(/[\\/]/).pop() || "server";
|
|
1620
1608
|
}
|
|
1621
|
-
|
|
1622
|
-
//#region ../../core/storage/own-entry.ts
|
|
1609
|
+
// ../../core/storage/own-entry.ts
|
|
1623
1610
|
function setOwnEntry(map, key, value) {
|
|
1624
1611
|
Object.defineProperty(map, key, {
|
|
1625
1612
|
value,
|
|
@@ -1631,8 +1618,7 @@ function setOwnEntry(map, key, value) {
|
|
|
1631
1618
|
function getOwnEntry(map, key) {
|
|
1632
1619
|
return map !== void 0 && Object.hasOwn(map, key) ? map[key] : void 0;
|
|
1633
1620
|
}
|
|
1634
|
-
|
|
1635
|
-
//#region ../../core/mcp/node/config.ts
|
|
1621
|
+
// ../../core/mcp/node/config.ts
|
|
1636
1622
|
function parseKeyValuePair(value, previous = {}) {
|
|
1637
1623
|
const parts = value.split("=");
|
|
1638
1624
|
const key = parts[0] ?? "";
|
|
@@ -1823,8 +1809,7 @@ function resolveServerConfigs(options, mode) {
|
|
|
1823
1809
|
}
|
|
1824
1810
|
return [];
|
|
1825
1811
|
}
|
|
1826
|
-
|
|
1827
|
-
//#region ../../core/auth/secret-storage-info.ts
|
|
1812
|
+
// ../../core/auth/secret-storage-info.ts
|
|
1828
1813
|
function secretStorageLabel(info) {
|
|
1829
1814
|
switch (info.kind) {
|
|
1830
1815
|
case "keyring": return "OS keychain";
|
|
@@ -1851,8 +1836,7 @@ function secretStorageSummary(info) {
|
|
|
1851
1836
|
if (info.reason === "fallback") parts.push("— fell back from the OS keychain");
|
|
1852
1837
|
return parts.join(" ");
|
|
1853
1838
|
}
|
|
1854
|
-
|
|
1855
|
-
//#region ../../core/auth/node/secret-store.ts
|
|
1839
|
+
// ../../core/auth/node/secret-store.ts
|
|
1856
1840
|
const SERVICE_NAME = "mcp-inspector";
|
|
1857
1841
|
let keyringLoad;
|
|
1858
1842
|
var KeyringModuleShapeError = class extends Error {
|
|
@@ -2072,8 +2056,7 @@ var SessionSecretStore = class extends InMemorySecretStore {
|
|
|
2072
2056
|
return false;
|
|
2073
2057
|
}
|
|
2074
2058
|
};
|
|
2075
|
-
|
|
2076
|
-
//#region ../../core/auth/node/file-lock.ts
|
|
2059
|
+
// ../../core/auth/node/file-lock.ts
|
|
2077
2060
|
const STALE_MS = 1e4;
|
|
2078
2061
|
const RETRY = {
|
|
2079
2062
|
retries: 20,
|
|
@@ -2205,8 +2188,7 @@ async function withSecretFileLock(filePath, fn) {
|
|
|
2205
2188
|
await release();
|
|
2206
2189
|
}
|
|
2207
2190
|
}
|
|
2208
|
-
|
|
2209
|
-
//#region ../../core/auth/node/file-secret-store.ts
|
|
2191
|
+
// ../../core/auth/node/file-secret-store.ts
|
|
2210
2192
|
const scrypt = (passphrase, salt, keylen, options) => new Promise((resolve, reject) => {
|
|
2211
2193
|
crypto$1.scrypt(passphrase, salt, keylen, options, (err, key) => {
|
|
2212
2194
|
/* v8 ignore next -- @preserve: node validates the cost parameters
|
|
@@ -2614,8 +2596,7 @@ async function readSecretFilePermissions(filePath) {
|
|
|
2614
2596
|
};
|
|
2615
2597
|
}
|
|
2616
2598
|
}
|
|
2617
|
-
|
|
2618
|
-
//#region ../../core/auth/node/secret-store-selection.ts
|
|
2599
|
+
// ../../core/auth/node/secret-store-selection.ts
|
|
2619
2600
|
const SECRET_STORE_ENV = "MCP_INSPECTOR_SECRET_STORE";
|
|
2620
2601
|
const SECRET_FILE_ENV = "MCP_INSPECTOR_SECRET_FILE";
|
|
2621
2602
|
const STORAGE_DIR_ENV = "MCP_STORAGE_DIR";
|
|
@@ -2922,8 +2903,7 @@ function defaultSecretStore() {
|
|
|
2922
2903
|
async function resolveConcreteSecretStore(store) {
|
|
2923
2904
|
return store instanceof DeferredSecretStore ? (await resolveSecretStore()).store : store;
|
|
2924
2905
|
}
|
|
2925
|
-
|
|
2926
|
-
//#region ../../core/mcp/node/server-secrets.ts
|
|
2906
|
+
// ../../core/mcp/node/server-secrets.ts
|
|
2927
2907
|
async function rehydrateMcpConfigFromKeychain(config, secretStore) {
|
|
2928
2908
|
const entries = Object.entries(config.mcpServers);
|
|
2929
2909
|
const secrets = await secretStoreGetMany(secretStore, entries.map(([serverId, stored]) => ({
|
|
@@ -2934,8 +2914,7 @@ async function rehydrateMcpConfigFromKeychain(config, secretStore) {
|
|
|
2934
2914
|
for (const [id, stored] of entries) out.mcpServers[id] = mergeSecretsIntoStored(stored, secrets[id] ?? {});
|
|
2935
2915
|
return out;
|
|
2936
2916
|
}
|
|
2937
|
-
|
|
2938
|
-
//#region ../../core/mcp/node/servers.ts
|
|
2917
|
+
// ../../core/mcp/node/servers.ts
|
|
2939
2918
|
function headersToServerSettings(headers) {
|
|
2940
2919
|
if (!headers || Object.keys(headers).length === 0) return;
|
|
2941
2920
|
return {
|
|
@@ -3013,8 +2992,7 @@ async function loadServerEntries(serverOptions) {
|
|
|
3013
2992
|
settings: mergeSettings(void 0, serverOptions)
|
|
3014
2993
|
} };
|
|
3015
2994
|
}
|
|
3016
|
-
|
|
3017
|
-
//#region ../../core/mcp/config.ts
|
|
2995
|
+
// ../../core/mcp/config.ts
|
|
3018
2996
|
function getServerType(config) {
|
|
3019
2997
|
if (!("type" in config) || config.type === void 0) return "stdio";
|
|
3020
2998
|
const type = config.type;
|
|
@@ -3023,8 +3001,7 @@ function getServerType(config) {
|
|
|
3023
3001
|
if (type === "streamable-http") return "streamable-http";
|
|
3024
3002
|
throw new Error(`Invalid server type: ${type}. Valid types are: stdio, sse, streamable-http`);
|
|
3025
3003
|
}
|
|
3026
|
-
|
|
3027
|
-
//#region ../../core/mcp/fetchTracking.ts
|
|
3004
|
+
// ../../core/mcp/fetchTracking.ts
|
|
3028
3005
|
const SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
3029
3006
|
"authorization",
|
|
3030
3007
|
"cookie",
|
|
@@ -3077,6 +3054,37 @@ function redactUrlQuery(url) {
|
|
|
3077
3054
|
}
|
|
3078
3055
|
}
|
|
3079
3056
|
const EMBEDDED_URL_PATTERN = /\bhttps?:\/\/(?:(?!https?:\/\/)[^\s"<>])+/gi;
|
|
3057
|
+
function newUrlScan() {
|
|
3058
|
+
return {
|
|
3059
|
+
phase: "path",
|
|
3060
|
+
name: "",
|
|
3061
|
+
inValue: false,
|
|
3062
|
+
sensitive: false,
|
|
3063
|
+
endsWithEquals: false
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
function advanceUrlScan(scan, piece, sensitiveNames) {
|
|
3067
|
+
for (const char of piece) {
|
|
3068
|
+
if (scan.phase === "fragment") break;
|
|
3069
|
+
if (char === "#") scan.phase = "fragment";
|
|
3070
|
+
else if (scan.phase === "path") {
|
|
3071
|
+
if (char === "?") scan.phase = "query";
|
|
3072
|
+
} else if (char === "&") {
|
|
3073
|
+
scan.name = "";
|
|
3074
|
+
scan.inValue = false;
|
|
3075
|
+
scan.sensitive = false;
|
|
3076
|
+
} else if (!scan.inValue) {
|
|
3077
|
+
if (char === "=") {
|
|
3078
|
+
scan.inValue = true;
|
|
3079
|
+
scan.sensitive = [...new URLSearchParams(`&${scan.name}=`).keys()].some((key) => sensitiveNames.has(key.toLowerCase()));
|
|
3080
|
+
} else scan.name += char;
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
scan.endsWithEquals = scan.phase === "query" && scan.inValue && piece.endsWith("=");
|
|
3084
|
+
}
|
|
3085
|
+
function opensSensitiveValue(scan) {
|
|
3086
|
+
return scan.endsWithEquals && scan.sensitive;
|
|
3087
|
+
}
|
|
3080
3088
|
const TRAILING_PUNCTUATION = /* @__PURE__ */ new Set([
|
|
3081
3089
|
".",
|
|
3082
3090
|
",",
|
|
@@ -3094,10 +3102,37 @@ function trailingPunctuationStart(match) {
|
|
|
3094
3102
|
return end;
|
|
3095
3103
|
}
|
|
3096
3104
|
function redactUrlsInText(text) {
|
|
3097
|
-
return text
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3105
|
+
return mapUrlsInText(text, redactUrlQuery);
|
|
3106
|
+
}
|
|
3107
|
+
function mapUrlsInText(text, redact, sensitiveNames = SENSITIVE_BODY_FIELDS) {
|
|
3108
|
+
let out = "";
|
|
3109
|
+
let copied = 0;
|
|
3110
|
+
let pieces = [];
|
|
3111
|
+
let scan = newUrlScan();
|
|
3112
|
+
const flush = () => {
|
|
3113
|
+
if (pieces.length === 0) return;
|
|
3114
|
+
const joined = pieces.join("");
|
|
3115
|
+
const end = trailingPunctuationStart(joined);
|
|
3116
|
+
const redacted = redact(joined.slice(0, end));
|
|
3117
|
+
out += pieces.length > 1 && redacted === joined.slice(0, end) ? pieces.map((piece) => redactMatch(piece, redact)).join("") : redacted + joined.slice(end);
|
|
3118
|
+
};
|
|
3119
|
+
for (const match of text.matchAll(EMBEDDED_URL_PATTERN)) {
|
|
3120
|
+
if (match.index !== copied || !opensSensitiveValue(scan)) {
|
|
3121
|
+
flush();
|
|
3122
|
+
out += text.slice(copied, match.index);
|
|
3123
|
+
pieces = [];
|
|
3124
|
+
scan = newUrlScan();
|
|
3125
|
+
}
|
|
3126
|
+
pieces.push(match[0]);
|
|
3127
|
+
advanceUrlScan(scan, match[0], sensitiveNames);
|
|
3128
|
+
copied = match.index + match[0].length;
|
|
3129
|
+
}
|
|
3130
|
+
flush();
|
|
3131
|
+
return out + text.slice(copied);
|
|
3132
|
+
}
|
|
3133
|
+
function redactMatch(match, redact) {
|
|
3134
|
+
const end = trailingPunctuationStart(match);
|
|
3135
|
+
return redact(match.slice(0, end)) + match.slice(end);
|
|
3101
3136
|
}
|
|
3102
3137
|
function redactJsonValue(value) {
|
|
3103
3138
|
if (Array.isArray(value)) return value.map(redactJsonValue);
|
|
@@ -3156,14 +3191,15 @@ function isLongLivedStreamResponse(method, contentType) {
|
|
|
3156
3191
|
}
|
|
3157
3192
|
const CHALLENGE_BODY_MAX_BYTES = 65536;
|
|
3158
3193
|
const CHALLENGE_BODY_READ_MS = 2e3;
|
|
3194
|
+
const TRACKED_BODY_MAX_BYTES = 1048576;
|
|
3159
3195
|
const TRUNCATED_BODY_SUFFIX = "\n[truncated]";
|
|
3160
3196
|
const WITHHELD_TRUNCATED_JSON_BODY = "[truncated JSON body withheld: an incomplete body cannot be redacted]";
|
|
3161
|
-
function
|
|
3197
|
+
function recordableBody(read, contentType) {
|
|
3162
3198
|
if (!read.truncated) return redactBody(read.text, contentType);
|
|
3163
3199
|
if ((contentType ?? "").toLowerCase().includes("json") || /^\s*[{[]/.test(read.text)) return WITHHELD_TRUNCATED_JSON_BODY;
|
|
3164
3200
|
return redactBody(read.text, contentType) + TRUNCATED_BODY_SUFFIX;
|
|
3165
3201
|
}
|
|
3166
|
-
async function
|
|
3202
|
+
async function readCappedBody(response, maxBytes, timeoutMs) {
|
|
3167
3203
|
let reader;
|
|
3168
3204
|
try {
|
|
3169
3205
|
const body = response.clone().body;
|
|
@@ -3177,20 +3213,23 @@ async function readChallengeBody(response) {
|
|
|
3177
3213
|
let text = "";
|
|
3178
3214
|
let bytes = 0;
|
|
3179
3215
|
let timer;
|
|
3180
|
-
const deadline = new Promise((resolve) => {
|
|
3181
|
-
timer = setTimeout(() => resolve("timeout"),
|
|
3216
|
+
const deadline = timeoutMs === void 0 ? void 0 : new Promise((resolve) => {
|
|
3217
|
+
timer = setTimeout(() => resolve("timeout"), timeoutMs);
|
|
3182
3218
|
});
|
|
3183
3219
|
try {
|
|
3184
|
-
|
|
3185
|
-
const next = await Promise.race([reader.read(), deadline]);
|
|
3220
|
+
for (;;) {
|
|
3221
|
+
const next = await (deadline ? Promise.race([reader.read(), deadline]) : reader.read());
|
|
3186
3222
|
if (next === "timeout") break;
|
|
3187
3223
|
if (next.done) return {
|
|
3188
3224
|
text: text + decoder.decode(),
|
|
3189
3225
|
truncated: false
|
|
3190
3226
|
};
|
|
3191
|
-
|
|
3227
|
+
if (next.value.byteLength === 0) continue;
|
|
3228
|
+
if (bytes >= maxBytes) break;
|
|
3229
|
+
const chunk = next.value.subarray(0, maxBytes - bytes);
|
|
3192
3230
|
bytes += chunk.byteLength;
|
|
3193
3231
|
text += decoder.decode(chunk, { stream: true });
|
|
3232
|
+
if (chunk.byteLength < next.value.byteLength) break;
|
|
3194
3233
|
}
|
|
3195
3234
|
reader.cancel().catch(() => {});
|
|
3196
3235
|
return {
|
|
@@ -3203,6 +3242,9 @@ async function readChallengeBody(response) {
|
|
|
3203
3242
|
clearTimeout(timer);
|
|
3204
3243
|
}
|
|
3205
3244
|
}
|
|
3245
|
+
function readChallengeBody(response) {
|
|
3246
|
+
return readCappedBody(response, CHALLENGE_BODY_MAX_BYTES, CHALLENGE_BODY_READ_MS);
|
|
3247
|
+
}
|
|
3206
3248
|
function longLivedStreamFraming(contentType) {
|
|
3207
3249
|
return contentType?.toLowerCase().includes("application/x-ndjson") ? "ndjson" : "sse";
|
|
3208
3250
|
}
|
|
@@ -3368,7 +3410,7 @@ function createFetchTracker(baseFetch, callbacks) {
|
|
|
3368
3410
|
};
|
|
3369
3411
|
if ((responseStatus === 401 || responseStatus === 403) && response.body && !response.bodyUsed) {
|
|
3370
3412
|
const read = await readChallengeBody(response);
|
|
3371
|
-
entry.responseBody = read === void 0 ? void 0 :
|
|
3413
|
+
entry.responseBody = read === void 0 ? void 0 : recordableBody(read, response.headers.get("content-type"));
|
|
3372
3414
|
callbacks.trackRequest?.(entry);
|
|
3373
3415
|
return response;
|
|
3374
3416
|
}
|
|
@@ -3376,17 +3418,17 @@ function createFetchTracker(baseFetch, callbacks) {
|
|
|
3376
3418
|
if (isLongLivedStream && response.body && !response.bodyUsed) watchLongLivedStream(response, id, longLivedStreamFraming(response.headers.get("content-type")), callbacks);
|
|
3377
3419
|
if (!isLongLivedStream && response.body && !response.bodyUsed) {
|
|
3378
3420
|
const responseContentType = response.headers.get("content-type");
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3421
|
+
readCappedBody(response, TRACKED_BODY_MAX_BYTES).then((read) => {
|
|
3422
|
+
if (read === void 0) return;
|
|
3423
|
+
try {
|
|
3424
|
+
callbacks.updateResponseBody?.(id, recordableBody(read, responseContentType));
|
|
3425
|
+
} catch {}
|
|
3426
|
+
});
|
|
3384
3427
|
}
|
|
3385
3428
|
return response;
|
|
3386
3429
|
};
|
|
3387
3430
|
}
|
|
3388
|
-
|
|
3389
|
-
//#region ../../core/auth/utils.ts
|
|
3431
|
+
// ../../core/auth/utils.ts
|
|
3390
3432
|
function parseHttpUrl(value, label) {
|
|
3391
3433
|
const trimmed = value.trim();
|
|
3392
3434
|
try {
|
|
@@ -3465,8 +3507,7 @@ function isUnauthorizedErrorDeep(err, seen) {
|
|
|
3465
3507
|
if (data !== null && typeof data === "object" && "cause" in data && isUnauthorizedErrorDeep(data.cause, seen)) return true;
|
|
3466
3508
|
return false;
|
|
3467
3509
|
}
|
|
3468
|
-
|
|
3469
|
-
//#region ../../core/auth/challenge.ts
|
|
3510
|
+
// ../../core/auth/challenge.ts
|
|
3470
3511
|
const EMA_STEP_UP_PENDING_URL = new URL("mcp-inspector:ema-step-up");
|
|
3471
3512
|
var AuthChallengeError = class extends Error {
|
|
3472
3513
|
authChallenge;
|
|
@@ -3612,8 +3653,7 @@ function isAuthChallengeError(err) {
|
|
|
3612
3653
|
const wwwAuthenticate = authChallenge?.raw?.wwwAuthenticate ?? err.wwwAuthenticate ?? err.headers?.get?.("WWW-Authenticate") ?? void 0;
|
|
3613
3654
|
return wwwAuthenticate !== void 0 && wwwAuthenticate.length > 0;
|
|
3614
3655
|
}
|
|
3615
|
-
|
|
3616
|
-
//#region ../../core/mcp/node/authChallengeFetch.ts
|
|
3656
|
+
// ../../core/mcp/node/authChallengeFetch.ts
|
|
3617
3657
|
function createAuthChallengeInterceptFetch(baseFetch) {
|
|
3618
3658
|
return async (input, init) => {
|
|
3619
3659
|
const response = await baseFetch(input, init);
|
|
@@ -3634,8 +3674,7 @@ function createAuthChallengeObserverFetch(baseFetch, onChallenge) {
|
|
|
3634
3674
|
return response;
|
|
3635
3675
|
};
|
|
3636
3676
|
}
|
|
3637
|
-
|
|
3638
|
-
//#region ../../core/mcp/node/proxyFetch.ts
|
|
3677
|
+
// ../../core/mcp/node/proxyFetch.ts
|
|
3639
3678
|
function asUndiciInit(init) {
|
|
3640
3679
|
return init;
|
|
3641
3680
|
}
|
|
@@ -3725,8 +3764,7 @@ function createProxyFetch() {
|
|
|
3725
3764
|
return (await loadedProxiedFetch)(input, init);
|
|
3726
3765
|
};
|
|
3727
3766
|
}
|
|
3728
|
-
|
|
3729
|
-
//#region ../../core/auth/requestTimeout.ts
|
|
3767
|
+
// ../../core/auth/requestTimeout.ts
|
|
3730
3768
|
const DEFAULT_OAUTH_REQUEST_TIMEOUT_MS = 3e4;
|
|
3731
3769
|
var OAuthRequestTimeoutError = class extends Error {
|
|
3732
3770
|
url;
|
|
@@ -3854,11 +3892,39 @@ function withOAuthRequestTimeout(fetchFn, timeoutMs = DEFAULT_OAUTH_REQUEST_TIME
|
|
|
3854
3892
|
}
|
|
3855
3893
|
};
|
|
3856
3894
|
}
|
|
3857
|
-
|
|
3858
|
-
//#region ../../core/mcp/node/fetchGuard.ts
|
|
3895
|
+
// ../../core/auth/fetchRefusal.ts
|
|
3859
3896
|
var FetchTargetError = class extends Error {
|
|
3860
3897
|
name = "FetchTargetError";
|
|
3898
|
+
url;
|
|
3899
|
+
constructor(message, url) {
|
|
3900
|
+
super(message);
|
|
3901
|
+
if (url !== void 0) this.url = url;
|
|
3902
|
+
}
|
|
3861
3903
|
};
|
|
3904
|
+
function findFetchTargetError(err) {
|
|
3905
|
+
let current = err;
|
|
3906
|
+
for (let depth = 0; depth < 8 && current instanceof Error; depth++) {
|
|
3907
|
+
if (current instanceof FetchTargetError) return current;
|
|
3908
|
+
current = current.cause;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
function formatFetchRefusal(refusal) {
|
|
3912
|
+
return `Refused to fetch ${refusal.url}: ${refusal.reason}`;
|
|
3913
|
+
}
|
|
3914
|
+
function withFetchRefusalReporting(base, onRefusal) {
|
|
3915
|
+
return async (input, init) => {
|
|
3916
|
+
try {
|
|
3917
|
+
return await base(input, init);
|
|
3918
|
+
} catch (err) {
|
|
3919
|
+
const refused = findFetchTargetError(err);
|
|
3920
|
+
if (refused) onRefusal({
|
|
3921
|
+
url: redactUrlQuery(refused.url ?? requestUrlOf$2(input)),
|
|
3922
|
+
reason: refused.message
|
|
3923
|
+
});
|
|
3924
|
+
throw err;
|
|
3925
|
+
}
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3862
3928
|
const REDIRECT_STATUSES = /* @__PURE__ */ new Set([
|
|
3863
3929
|
301,
|
|
3864
3930
|
302,
|
|
@@ -3867,11 +3933,12 @@ const REDIRECT_STATUSES = /* @__PURE__ */ new Set([
|
|
|
3867
3933
|
308
|
|
3868
3934
|
]);
|
|
3869
3935
|
const resolveWithSystemDns = async (hostname) => (await lookup(hostname, { all: true })).map((r) => r.address);
|
|
3936
|
+
const METADATA_IPV4_ADDRESSES = /* @__PURE__ */ new Set(["100.100.100.200", "192.0.0.192"]);
|
|
3870
3937
|
function isBlockedAddress(ip) {
|
|
3871
3938
|
const kind = isIP(ip);
|
|
3872
3939
|
if (kind === 4) {
|
|
3873
3940
|
const [a, b] = ip.split(".").map(Number);
|
|
3874
|
-
return a === 169 && b === 254;
|
|
3941
|
+
return a === 169 && b === 254 || METADATA_IPV4_ADDRESSES.has(ip);
|
|
3875
3942
|
}
|
|
3876
3943
|
if (kind !== 6) return false;
|
|
3877
3944
|
const addr = ip.toLowerCase();
|
|
@@ -4028,27 +4095,35 @@ async function guardedFetch(url, init, options = {}) {
|
|
|
4028
4095
|
headers: init.headers
|
|
4029
4096
|
};
|
|
4030
4097
|
for (let hop = 0; hop <= 5; hop++) {
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4098
|
+
let res;
|
|
4099
|
+
try {
|
|
4100
|
+
await assertAllowedTarget(request.url, resolveHost, viaProxy, init.signal);
|
|
4101
|
+
res = await fetchFn(request.url.href, {
|
|
4102
|
+
method: request.method,
|
|
4103
|
+
headers: new Headers(request.headers),
|
|
4104
|
+
body: request.body,
|
|
4105
|
+
signal: init.signal,
|
|
4106
|
+
redirect: "manual"
|
|
4107
|
+
});
|
|
4108
|
+
} catch (err) {
|
|
4109
|
+
stampRefusedUrl(err, request.url);
|
|
4110
|
+
throw err;
|
|
4111
|
+
}
|
|
4039
4112
|
const location = res.headers.get("location");
|
|
4040
4113
|
if (!REDIRECT_STATUSES.has(res.status) || location === null) return res;
|
|
4041
4114
|
res.body?.cancel().catch(() => {});
|
|
4042
|
-
|
|
4115
|
+
try {
|
|
4116
|
+
request = nextRedirectRequest(request, res.status, location);
|
|
4117
|
+
} catch (err) {
|
|
4118
|
+
stampRefusedUrl(err, request.url);
|
|
4119
|
+
throw err;
|
|
4120
|
+
}
|
|
4043
4121
|
}
|
|
4044
|
-
throw new FetchTargetError(`Refusing to follow more than 5 redirects
|
|
4122
|
+
throw new FetchTargetError(`Refusing to follow more than 5 redirects`, request.url.href);
|
|
4045
4123
|
}
|
|
4046
|
-
function
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
if (current instanceof FetchTargetError) return current;
|
|
4050
|
-
current = current.cause;
|
|
4051
|
-
}
|
|
4124
|
+
function stampRefusedUrl(err, url) {
|
|
4125
|
+
const refused = findFetchTargetError(err);
|
|
4126
|
+
if (refused && refused.url === void 0) refused.url = url.href;
|
|
4052
4127
|
}
|
|
4053
4128
|
async function bodyText(input, init) {
|
|
4054
4129
|
const body = init?.body !== void 0 ? init.body : input instanceof Request && input.body !== null ? await input.clone().text() : void 0;
|
|
@@ -4075,8 +4150,7 @@ function createGuardedFetch(options = {}) {
|
|
|
4075
4150
|
}
|
|
4076
4151
|
};
|
|
4077
4152
|
}
|
|
4078
|
-
|
|
4079
|
-
//#region ../../core/auth/routeOAuthRequests.ts
|
|
4153
|
+
// ../../core/auth/routeOAuthRequests.ts
|
|
4080
4154
|
function isJsonRpcMessage(value) {
|
|
4081
4155
|
return typeof value === "object" && value !== null && value.jsonrpc === "2.0";
|
|
4082
4156
|
}
|
|
@@ -4100,8 +4174,7 @@ function isMcpShapedRequest(input, init) {
|
|
|
4100
4174
|
function routeOAuthRequests(mcpFetch, oauthFetch, isMcpEndpoint) {
|
|
4101
4175
|
return (input, init) => isMcpShapedRequest(input, init) && isMcpEndpoint(requestUrlOf$2(input), requestHeadersOf(input, init)) ? mcpFetch(input, init) : oauthFetch(input, init);
|
|
4102
4176
|
}
|
|
4103
|
-
|
|
4104
|
-
//#region ../../core/mcp/node/notificationHeadersFetch.ts
|
|
4177
|
+
// ../../core/mcp/node/notificationHeadersFetch.ts
|
|
4105
4178
|
function createNotificationHeadersFetch(baseFetch) {
|
|
4106
4179
|
return (input, init) => {
|
|
4107
4180
|
const method = modernNotificationMethod(init);
|
|
@@ -4137,8 +4210,7 @@ function modernNotificationMethod(init) {
|
|
|
4137
4210
|
function isRecord$4(value) {
|
|
4138
4211
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4139
4212
|
}
|
|
4140
|
-
|
|
4141
|
-
//#region ../../core/mcp/node/suppressNotificationStreamFetch.ts
|
|
4213
|
+
// ../../core/mcp/node/suppressNotificationStreamFetch.ts
|
|
4142
4214
|
function createSuppressNotificationStreamFetch(baseFetch, endpoint) {
|
|
4143
4215
|
return async (input, init) => {
|
|
4144
4216
|
if (isStandaloneStreamRequest(input, init, endpoint)) return new Response(null, {
|
|
@@ -4164,8 +4236,7 @@ function isStandaloneStreamRequest(input, init, endpoint) {
|
|
|
4164
4236
|
const headers = new Headers(init?.headers ?? request?.headers);
|
|
4165
4237
|
return (headers.get("accept")?.toLowerCase() ?? "").includes("text/event-stream") && !headers.has("last-event-id");
|
|
4166
4238
|
}
|
|
4167
|
-
|
|
4168
|
-
//#region ../../core/mcp/node/transport.ts
|
|
4239
|
+
// ../../core/mcp/node/transport.ts
|
|
4169
4240
|
function headersFromSettings(settings) {
|
|
4170
4241
|
if (!settings || settings.headers.length === 0) return void 0;
|
|
4171
4242
|
const out = {};
|
|
@@ -4247,8 +4318,7 @@ function createTransportNode(config, options = {}) {
|
|
|
4247
4318
|
}) };
|
|
4248
4319
|
}
|
|
4249
4320
|
}
|
|
4250
|
-
|
|
4251
|
-
//#region ../../core/client/config-parse.ts
|
|
4321
|
+
// ../../core/client/config-parse.ts
|
|
4252
4322
|
function isAbsoluteHttpUrl(value) {
|
|
4253
4323
|
let url;
|
|
4254
4324
|
try {
|
|
@@ -4331,8 +4401,7 @@ const ClientConfigSchema = z$1.object({
|
|
|
4331
4401
|
function parseClientConfig(raw) {
|
|
4332
4402
|
return ClientConfigSchema.parse(raw);
|
|
4333
4403
|
}
|
|
4334
|
-
|
|
4335
|
-
//#region ../../core/client/secrets.ts
|
|
4404
|
+
// ../../core/client/secrets.ts
|
|
4336
4405
|
const CLIENT_KEYCHAIN_ID = "client";
|
|
4337
4406
|
function hasClientPlaintextSecret(config) {
|
|
4338
4407
|
const secret = config.enterpriseManagedAuth?.idp?.clientSecret;
|
|
@@ -4373,8 +4442,7 @@ function mergeSecretsIntoClientConfig(config, secrets) {
|
|
|
4373
4442
|
}
|
|
4374
4443
|
};
|
|
4375
4444
|
}
|
|
4376
|
-
|
|
4377
|
-
//#region ../../core/client/node-persistence.ts
|
|
4445
|
+
// ../../core/client/node-persistence.ts
|
|
4378
4446
|
async function withClientConfigLock(filePath, action, body) {
|
|
4379
4447
|
let entered = false;
|
|
4380
4448
|
try {
|
|
@@ -4424,8 +4492,7 @@ async function readClientConfigStore(filePath, secretStore) {
|
|
|
4424
4492
|
const secrets = await readIdpSecretFromKeychain(secretStore);
|
|
4425
4493
|
return mergeSecretsIntoClientConfig(config, secrets);
|
|
4426
4494
|
}
|
|
4427
|
-
|
|
4428
|
-
//#region ../../core/client/config.ts
|
|
4495
|
+
// ../../core/client/config.ts
|
|
4429
4496
|
function getClientConfigFilePath(customPath) {
|
|
4430
4497
|
return customPath ?? getStoreFilePath(getDefaultStorageDir(), "client");
|
|
4431
4498
|
}
|
|
@@ -4436,8 +4503,7 @@ async function loadClientConfig(options) {
|
|
|
4436
4503
|
if (raw === null) return {};
|
|
4437
4504
|
return parseClientConfig(parseStore(raw));
|
|
4438
4505
|
}
|
|
4439
|
-
|
|
4440
|
-
//#region ../../core/client/types.ts
|
|
4506
|
+
// ../../core/client/types.ts
|
|
4441
4507
|
function isEnterpriseManagedAuthEnabled(config) {
|
|
4442
4508
|
const ema = config.enterpriseManagedAuth;
|
|
4443
4509
|
if (!ema?.idp) return false;
|
|
@@ -4454,8 +4520,7 @@ function getActiveCimdClientMetadataUrl(config) {
|
|
|
4454
4520
|
if (!isCimdEnabled(config)) return void 0;
|
|
4455
4521
|
return config.cimd?.clientMetadataUrl?.trim() || void 0;
|
|
4456
4522
|
}
|
|
4457
|
-
|
|
4458
|
-
//#region ../../core/client/runner.ts
|
|
4523
|
+
// ../../core/client/runner.ts
|
|
4459
4524
|
async function loadRunnerClientConfig(options) {
|
|
4460
4525
|
return loadClientConfig({
|
|
4461
4526
|
filePath: options?.clientConfigPath?.trim() || process.env.MCP_CLIENT_CONFIG_PATH?.trim() || void 0,
|
|
@@ -4498,8 +4563,7 @@ function buildRunnerClientAuthOptions(clientConfig, savedSettings, cliOverrides)
|
|
|
4498
4563
|
...oauth && { directAuthRecovery: true }
|
|
4499
4564
|
};
|
|
4500
4565
|
}
|
|
4501
|
-
|
|
4502
|
-
//#region ../../core/node/version.ts
|
|
4566
|
+
// ../../core/node/version.ts
|
|
4503
4567
|
const ROOT_PACKAGE_NAME = "@modelcontextprotocol/inspector";
|
|
4504
4568
|
function readInspectorVersion(callerUrl) {
|
|
4505
4569
|
const startDir = dirname$1(fileURLToPath$1(callerUrl));
|
|
@@ -4516,8 +4580,7 @@ function readInspectorVersion(callerUrl) {
|
|
|
4516
4580
|
}
|
|
4517
4581
|
throw new Error(`Could not locate the ${ROOT_PACKAGE_NAME} root package.json above ${startDir}`);
|
|
4518
4582
|
}
|
|
4519
|
-
|
|
4520
|
-
//#region ../../core/node/hostUrl.ts
|
|
4583
|
+
// ../../core/node/hostUrl.ts
|
|
4521
4584
|
function stripBrackets(host) {
|
|
4522
4585
|
return host.replace(/^\[(.*)\]$/, "$1");
|
|
4523
4586
|
}
|
|
@@ -4545,8 +4608,7 @@ function isLoopbackHost(host) {
|
|
|
4545
4608
|
const h = canonicalUrlHost(host).replace(/\.$/, "");
|
|
4546
4609
|
return h === "localhost" || h === "[::1]" || /^127(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/.test(h);
|
|
4547
4610
|
}
|
|
4548
|
-
|
|
4549
|
-
//#region ../../core/auth/node/runner-oauth-callback.ts
|
|
4611
|
+
// ../../core/auth/node/runner-oauth-callback.ts
|
|
4550
4612
|
const RUNNER_OAUTH_CALLBACK_DEFAULT_HOSTNAME = "127.0.0.1";
|
|
4551
4613
|
const RUNNER_OAUTH_CALLBACK_DEFAULT_PORT = 6276;
|
|
4552
4614
|
const RUNNER_OAUTH_CALLBACK_PATH = "/oauth/callback";
|
|
@@ -4590,8 +4652,7 @@ function parseRunnerOAuthCallbackUrl(cliCallbackUrl) {
|
|
|
4590
4652
|
function formatRunnerOAuthRedirectUrl(config) {
|
|
4591
4653
|
return `http://${formatHostForUrl(config.hostname)}:${config.port}${config.pathname}`;
|
|
4592
4654
|
}
|
|
4593
|
-
|
|
4594
|
-
//#region ../../core/json/xMcpHeader.ts
|
|
4655
|
+
// ../../core/json/xMcpHeader.ts
|
|
4595
4656
|
const X_MCP_HEADER_KEY = "x-mcp-header";
|
|
4596
4657
|
const MCP_PARAM_HEADER_PREFIX = "Mcp-Param-";
|
|
4597
4658
|
const RFC9110_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
@@ -4739,8 +4800,7 @@ function mcpParamHeadersForTool(tool, args) {
|
|
|
4739
4800
|
if (!scan.valid || scan.declarations.length === 0) return {};
|
|
4740
4801
|
return buildMcpParamHeaders(scan.declarations, args);
|
|
4741
4802
|
}
|
|
4742
|
-
|
|
4743
|
-
//#region ../../core/mcp/subscriptionAck.ts
|
|
4803
|
+
// ../../core/mcp/subscriptionAck.ts
|
|
4744
4804
|
const NEVER_ACKNOWLEDGED_SDK_MESSAGE = "closed the subscription gracefully before acknowledging";
|
|
4745
4805
|
const NEVER_ACKNOWLEDGED_SUBSCRIPTION_MESSAGE = "The server closed the subscription without acknowledging it. A subscriptions/listen request must first be answered with a notifications/subscriptions/acknowledged notification; a JSON-RPC result for the listen id means graceful closure. Not retrying — the server would answer the same way again.";
|
|
4746
4806
|
function isNeverAcknowledgedSubscriptionClose(error) {
|
|
@@ -4750,8 +4810,7 @@ function subscriptionFailureMessage(error) {
|
|
|
4750
4810
|
if (isNeverAcknowledgedSubscriptionClose(error)) return NEVER_ACKNOWLEDGED_SUBSCRIPTION_MESSAGE;
|
|
4751
4811
|
return error instanceof Error ? error.message : String(error);
|
|
4752
4812
|
}
|
|
4753
|
-
|
|
4754
|
-
//#region ../../core/mcp/subscriptionRefusal.ts
|
|
4813
|
+
// ../../core/mcp/subscriptionRefusal.ts
|
|
4755
4814
|
const REFUSAL_STATUSES = /* @__PURE__ */ new Set([
|
|
4756
4815
|
400,
|
|
4757
4816
|
403,
|
|
@@ -4768,8 +4827,7 @@ function subscriptionListenRefusal(error) {
|
|
|
4768
4827
|
function subscriptionListenRefusalMessage(refusal) {
|
|
4769
4828
|
return `The server refused subscriptions/listen (HTTP ${refusal.statusText ? `${refusal.status} ${refusal.statusText}` : String(refusal.status)}). Not retrying — the server would answer the same way again.`;
|
|
4770
4829
|
}
|
|
4771
|
-
|
|
4772
|
-
//#region ../../core/mcp/messageTrackingTransport.ts
|
|
4830
|
+
// ../../core/mcp/messageTrackingTransport.ts
|
|
4773
4831
|
var MessageTrackingTransport = class {
|
|
4774
4832
|
baseTransport;
|
|
4775
4833
|
callbacks;
|
|
@@ -4842,8 +4900,7 @@ var MessageTrackingTransport = class {
|
|
|
4842
4900
|
return this.negotiatedProtocolVersion;
|
|
4843
4901
|
}
|
|
4844
4902
|
};
|
|
4845
|
-
|
|
4846
|
-
//#region ../../core/extension/tasks/errors.ts
|
|
4903
|
+
// ../../core/extension/tasks/errors.ts
|
|
4847
4904
|
function abortError(signal) {
|
|
4848
4905
|
return signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
4849
4906
|
}
|
|
@@ -4857,14 +4914,12 @@ function toProtocolError(reason) {
|
|
|
4857
4914
|
const normalized = unwrapTaskDispatchError(reason);
|
|
4858
4915
|
return normalized instanceof ProtocolError ? normalized : new ProtocolError(ProtocolErrorCode.InternalError, normalized instanceof Error ? normalized.message : String(normalized));
|
|
4859
4916
|
}
|
|
4860
|
-
|
|
4861
|
-
//#region ../../core/extension/tasks/notificationSchemas.ts
|
|
4917
|
+
// ../../core/extension/tasks/notificationSchemas.ts
|
|
4862
4918
|
const TasksListChangedNotificationSchema = NotificationSchema.extend({
|
|
4863
4919
|
method: z.literal("notifications/tasks/list_changed"),
|
|
4864
4920
|
params: z.record(z.string(), z.unknown()).optional()
|
|
4865
4921
|
});
|
|
4866
|
-
|
|
4867
|
-
//#region ../../core/extension/tasks/progress.ts
|
|
4922
|
+
// ../../core/extension/tasks/progress.ts
|
|
4868
4923
|
var TaskProgressRouter = class {
|
|
4869
4924
|
taskIds = /* @__PURE__ */ new Map();
|
|
4870
4925
|
owners = /* @__PURE__ */ new Map();
|
|
@@ -4895,8 +4950,7 @@ var TaskProgressRouter = class {
|
|
|
4895
4950
|
this.owners.clear();
|
|
4896
4951
|
}
|
|
4897
4952
|
};
|
|
4898
|
-
|
|
4899
|
-
//#region ../../core/extension/tasks/rawWireChannel.ts
|
|
4953
|
+
// ../../core/extension/tasks/rawWireChannel.ts
|
|
4900
4954
|
const RAW_WIRE_ID_PREFIX = "inspector-ext-";
|
|
4901
4955
|
var RawWireChannel = class {
|
|
4902
4956
|
pending = /* @__PURE__ */ new Map();
|
|
@@ -5025,8 +5079,7 @@ var RawWireChannel = class {
|
|
|
5025
5079
|
}
|
|
5026
5080
|
}
|
|
5027
5081
|
};
|
|
5028
|
-
|
|
5029
|
-
//#region ../../core/extension/tasks/session.ts
|
|
5082
|
+
// ../../core/extension/tasks/session.ts
|
|
5030
5083
|
function taskSessionEndpointId(config, clientInfo) {
|
|
5031
5084
|
return createTaskSessionEndpointId("inspector", config.type === "sse" || config.type === "streamable-http" ? {
|
|
5032
5085
|
host: clientInfo,
|
|
@@ -5049,8 +5102,7 @@ function isTasksExtensionNegotiated(era, capabilities) {
|
|
|
5049
5102
|
const extension = capabilities?.extensions?.[TASKS_EXTENSION_KEY];
|
|
5050
5103
|
return extension !== null && typeof extension === "object" && !Array.isArray(extension) && Object.keys(extension).length === 0;
|
|
5051
5104
|
}
|
|
5052
|
-
|
|
5053
|
-
//#region ../../core/extension/tasks/wire.ts
|
|
5105
|
+
// ../../core/extension/tasks/wire.ts
|
|
5054
5106
|
const taskToolResultCodec = runtimeCodecFromStandardSchema({ "~standard": {
|
|
5055
5107
|
version: 1,
|
|
5056
5108
|
vendor: "mcp-inspector",
|
|
@@ -5087,8 +5139,7 @@ function taskInputOrigin(delivery) {
|
|
|
5087
5139
|
if (delivery === "request-retry") return "input-required";
|
|
5088
5140
|
return "server-request";
|
|
5089
5141
|
}
|
|
5090
|
-
|
|
5091
|
-
//#region ../../core/mcp/extensions.ts
|
|
5142
|
+
// ../../core/mcp/extensions.ts
|
|
5092
5143
|
const EMA_EXTENSION_KEY = "io.modelcontextprotocol/enterprise-managed-authorization";
|
|
5093
5144
|
const UI_EXTENSION_KEY = "io.modelcontextprotocol/ui";
|
|
5094
5145
|
const MCP_APP_MIME_TYPE = RESOURCE_MIME_TYPE;
|
|
@@ -5125,8 +5176,7 @@ function buildClientExtensions(input) {
|
|
|
5125
5176
|
if (input.enterpriseManaged) map[EMA_EXTENSION_KEY] = {};
|
|
5126
5177
|
return map;
|
|
5127
5178
|
}
|
|
5128
|
-
|
|
5129
|
-
//#region ../../core/mcp/appElicitation.ts
|
|
5179
|
+
// ../../core/mcp/appElicitation.ts
|
|
5130
5180
|
function uiExtension(capabilities) {
|
|
5131
5181
|
const ext = capabilities?.extensions?.[UI_EXTENSION_KEY];
|
|
5132
5182
|
return typeof ext === "object" && ext !== null ? ext : void 0;
|
|
@@ -5181,8 +5231,7 @@ function validateAppElicitResult(provider, params, result) {
|
|
|
5181
5231
|
return;
|
|
5182
5232
|
}
|
|
5183
5233
|
}
|
|
5184
|
-
|
|
5185
|
-
//#region ../../core/mcp/toolOutputValidation.ts
|
|
5234
|
+
// ../../core/mcp/toolOutputValidation.ts
|
|
5186
5235
|
function validateToolOutput(provider, tool, result) {
|
|
5187
5236
|
if (!tool.outputSchema) return void 0;
|
|
5188
5237
|
const structured = result.structuredContent;
|
|
@@ -5194,8 +5243,7 @@ function validateToolOutput(provider, tool, result) {
|
|
|
5194
5243
|
return;
|
|
5195
5244
|
}
|
|
5196
5245
|
}
|
|
5197
|
-
|
|
5198
|
-
//#region ../../core/json/linearRegExp.ts
|
|
5246
|
+
// ../../core/json/linearRegExp.ts
|
|
5199
5247
|
var CharMatcher = class {
|
|
5200
5248
|
re;
|
|
5201
5249
|
ascii = /* @__PURE__ */ new Uint8Array(128);
|
|
@@ -5690,8 +5738,7 @@ function compileLinearRegExp(pattern, unicode, budget) {
|
|
|
5690
5738
|
};
|
|
5691
5739
|
}
|
|
5692
5740
|
}
|
|
5693
|
-
|
|
5694
|
-
//#region ../../core/mcp/linearPatternValidator.ts
|
|
5741
|
+
// ../../core/mcp/linearPatternValidator.ts
|
|
5695
5742
|
const PATTERN_EVALUATION_BUDGET = 2e7;
|
|
5696
5743
|
const SCHEMA_COMPILE_BUDGET = {
|
|
5697
5744
|
steps: 10 * MAX_COMPILE_STEPS,
|
|
@@ -5915,8 +5962,7 @@ function stripExecution(tool) {
|
|
|
5915
5962
|
function eraToolItemSchema(wire, normalize) {
|
|
5916
5963
|
return wire.transform((parsed) => normalize(parsed));
|
|
5917
5964
|
}
|
|
5918
|
-
|
|
5919
|
-
//#region ../../core/mcp/uriTemplate.ts
|
|
5965
|
+
// ../../core/mcp/uriTemplate.ts
|
|
5920
5966
|
const OPERATORS = [
|
|
5921
5967
|
"+",
|
|
5922
5968
|
"#",
|
|
@@ -6141,8 +6187,7 @@ function valueLengthError(values, names) {
|
|
|
6141
6187
|
function declaredNames(parts) {
|
|
6142
6188
|
return [...new Set(parts.flatMap((part) => part.kind === "expression" ? part.names : []))];
|
|
6143
6189
|
}
|
|
6144
|
-
|
|
6145
|
-
//#region ../../core/mcp/typedEventTarget.ts
|
|
6190
|
+
// ../../core/mcp/typedEventTarget.ts
|
|
6146
6191
|
var TypedEventGeneric = class extends CustomEvent {
|
|
6147
6192
|
constructor(type, detail) {
|
|
6148
6193
|
super(type, { detail });
|
|
@@ -6168,11 +6213,9 @@ var TypedEventTarget = class extends EventTarget {
|
|
|
6168
6213
|
super.removeEventListener(type, listener, options);
|
|
6169
6214
|
}
|
|
6170
6215
|
};
|
|
6171
|
-
|
|
6172
|
-
//#region ../../core/mcp/inspectorClientEventTarget.ts
|
|
6216
|
+
// ../../core/mcp/inspectorClientEventTarget.ts
|
|
6173
6217
|
var InspectorClientEventTarget = class extends TypedEventTarget {};
|
|
6174
|
-
|
|
6175
|
-
//#region ../../core/mcp/samplingCreateMessage.ts
|
|
6218
|
+
// ../../core/mcp/samplingCreateMessage.ts
|
|
6176
6219
|
var SamplingCreateMessage = class {
|
|
6177
6220
|
id;
|
|
6178
6221
|
timestamp;
|
|
@@ -6216,8 +6259,7 @@ var SamplingCreateMessage = class {
|
|
|
6216
6259
|
this.onRemove(this.id);
|
|
6217
6260
|
}
|
|
6218
6261
|
};
|
|
6219
|
-
|
|
6220
|
-
//#region ../../core/mcp/elicitationCreateMessage.ts
|
|
6262
|
+
// ../../core/mcp/elicitationCreateMessage.ts
|
|
6221
6263
|
var ElicitationCreateMessage = class {
|
|
6222
6264
|
id;
|
|
6223
6265
|
timestamp;
|
|
@@ -6264,8 +6306,7 @@ var ElicitationCreateMessage = class {
|
|
|
6264
6306
|
this.onRemove(this.id);
|
|
6265
6307
|
}
|
|
6266
6308
|
};
|
|
6267
|
-
|
|
6268
|
-
//#region ../../core/mcp/urlElicitation.ts
|
|
6309
|
+
// ../../core/mcp/urlElicitation.ts
|
|
6269
6310
|
var UrlElicitationLoopError = class extends Error {
|
|
6270
6311
|
url;
|
|
6271
6312
|
constructor(url) {
|
|
@@ -6279,8 +6320,7 @@ function getUrlElicitationsFromError(error) {
|
|
|
6279
6320
|
if (error instanceof ProtocolError && error.code === ProtocolErrorCode.UrlElicitationRequired) return error.data?.elicitations ?? [];
|
|
6280
6321
|
return null;
|
|
6281
6322
|
}
|
|
6282
|
-
|
|
6283
|
-
//#region ../../core/mcp/toolCallCancelledError.ts
|
|
6323
|
+
// ../../core/mcp/toolCallCancelledError.ts
|
|
6284
6324
|
var ToolCallCancelledError = class extends Error {
|
|
6285
6325
|
toolName;
|
|
6286
6326
|
constructor(toolName) {
|
|
@@ -6289,8 +6329,7 @@ var ToolCallCancelledError = class extends Error {
|
|
|
6289
6329
|
this.toolName = toolName;
|
|
6290
6330
|
}
|
|
6291
6331
|
};
|
|
6292
|
-
|
|
6293
|
-
//#region ../../core/auth/endpointOverrides.ts
|
|
6332
|
+
// ../../core/auth/endpointOverrides.ts
|
|
6294
6333
|
const OVERRIDE_FIELDS = {
|
|
6295
6334
|
authorizationUrl: "authorization_endpoint",
|
|
6296
6335
|
tokenUrl: "token_endpoint"
|
|
@@ -6467,8 +6506,7 @@ function withOAuthEndpointOverrides(fetchFn, getOverrides) {
|
|
|
6467
6506
|
return responseWithBody(response, JSON.stringify(applyOAuthEndpointOverrides(parsed, overrides)));
|
|
6468
6507
|
};
|
|
6469
6508
|
}
|
|
6470
|
-
|
|
6471
|
-
//#region ../../core/auth/oidcDiscoveryCompat.ts
|
|
6509
|
+
// ../../core/auth/oidcDiscoveryCompat.ts
|
|
6472
6510
|
const RFC8414_WELL_KNOWN = "/.well-known/oauth-authorization-server";
|
|
6473
6511
|
const OIDC_WELL_KNOWN$1 = "/.well-known/openid-configuration";
|
|
6474
6512
|
const COMPAT_SOURCE_HEADER = "x-inspector-oauth-metadata-source";
|
|
@@ -6590,8 +6628,7 @@ function withRfc8414OidcCompat(fetchFn) {
|
|
|
6590
6628
|
return response;
|
|
6591
6629
|
};
|
|
6592
6630
|
}
|
|
6593
|
-
|
|
6594
|
-
//#region ../../core/logging/logger.ts
|
|
6631
|
+
// ../../core/logging/logger.ts
|
|
6595
6632
|
const noop = () => {};
|
|
6596
6633
|
function createSilentLogger() {
|
|
6597
6634
|
const logger = {
|
|
@@ -6608,8 +6645,7 @@ function createSilentLogger() {
|
|
|
6608
6645
|
return logger;
|
|
6609
6646
|
}
|
|
6610
6647
|
const silentLogger = createSilentLogger();
|
|
6611
|
-
|
|
6612
|
-
//#region ../../core/mcp/connectionDiagnostics.ts
|
|
6648
|
+
// ../../core/mcp/connectionDiagnostics.ts
|
|
6613
6649
|
function isRequestTimeoutData(value) {
|
|
6614
6650
|
return typeof value === "object" && value !== null && typeof value.timeout === "number";
|
|
6615
6651
|
}
|
|
@@ -6631,7 +6667,7 @@ function httpStatusTextOf(err) {
|
|
|
6631
6667
|
if (typeof err !== "object" || err === null || !("statusText" in err)) return;
|
|
6632
6668
|
return typeof err.statusText === "string" ? err.statusText : void 0;
|
|
6633
6669
|
}
|
|
6634
|
-
function formatDuration(ms) {
|
|
6670
|
+
function formatDuration$1(ms) {
|
|
6635
6671
|
const clamped = Math.max(0, ms);
|
|
6636
6672
|
if (clamped < 1e3) return `${Math.round(clamped)}ms`;
|
|
6637
6673
|
const totalSeconds = Math.round(clamped / 1e3);
|
|
@@ -6654,7 +6690,7 @@ function plural(count, noun) {
|
|
|
6654
6690
|
}
|
|
6655
6691
|
function describeOutstanding(requests, now) {
|
|
6656
6692
|
if (requests.length === 0) return "No requests are unanswered.";
|
|
6657
|
-
const listed = requests.slice(0, 5).map((r) => `${r.method} (sent ${formatDuration(now - r.sentAt)} ago)`);
|
|
6693
|
+
const listed = requests.slice(0, 5).map((r) => `${r.method} (sent ${formatDuration$1(now - r.sentAt)} ago)`);
|
|
6658
6694
|
const rest = requests.length - listed.length;
|
|
6659
6695
|
const tail = rest > 0 ? `, and ${rest} more` : "";
|
|
6660
6696
|
const verb = requests.length === 1 ? "is" : "are";
|
|
@@ -6662,14 +6698,14 @@ function describeOutstanding(requests, now) {
|
|
|
6662
6698
|
}
|
|
6663
6699
|
function describeLastResponse(lastResponse, now) {
|
|
6664
6700
|
if (!lastResponse) return "No response has been received this session.";
|
|
6665
|
-
return `Last response received ${formatDuration(now - lastResponse.receivedAt)} ago (${lastResponse.method}).`;
|
|
6701
|
+
return `Last response received ${formatDuration$1(now - lastResponse.receivedAt)} ago (${lastResponse.method}).`;
|
|
6666
6702
|
}
|
|
6667
6703
|
function describeStream(stream, now) {
|
|
6668
6704
|
if (!stream) return void 0;
|
|
6669
6705
|
const endpoint = describeStreamEndpoint(stream.url);
|
|
6670
6706
|
const events = plural(stream.eventCount, "event");
|
|
6671
|
-
if (stream.closedAt !== void 0) return `Notification stream (${endpoint}) closed ${formatDuration(now - stream.closedAt)} ago after ${formatDuration(stream.closedAt - stream.openedAt)}, ${events} delivered.`;
|
|
6672
|
-
return `Notification stream (${endpoint}) open for ${formatDuration(now - stream.openedAt)}, ${events} delivered.`;
|
|
6707
|
+
if (stream.closedAt !== void 0) return `Notification stream (${endpoint}) closed ${formatDuration$1(now - stream.closedAt)} ago after ${formatDuration$1(stream.closedAt - stream.openedAt)}, ${events} delivered.`;
|
|
6708
|
+
return `Notification stream (${endpoint}) open for ${formatDuration$1(now - stream.openedAt)}, ${events} delivered.`;
|
|
6673
6709
|
}
|
|
6674
6710
|
function describeConnectionDiagnostics(diagnostics) {
|
|
6675
6711
|
const now = diagnostics.capturedAt;
|
|
@@ -6686,7 +6722,7 @@ function annotateRequestTimeout(err, method, diagnostics) {
|
|
|
6686
6722
|
method,
|
|
6687
6723
|
diagnostics
|
|
6688
6724
|
};
|
|
6689
|
-
const message = `Request timed out after ${formatDuration(err.data.timeout)} (${method}). ${describeConnectionDiagnostics(diagnostics)}`;
|
|
6725
|
+
const message = `Request timed out after ${formatDuration$1(err.data.timeout)} (${method}). ${describeConnectionDiagnostics(diagnostics)}`;
|
|
6690
6726
|
const annotated = new SdkError(SdkErrorCode.RequestTimeout, message, data);
|
|
6691
6727
|
annotated.cause = err;
|
|
6692
6728
|
return annotated;
|
|
@@ -6756,7 +6792,7 @@ function attachRetryAfter(err, retryAfter) {
|
|
|
6756
6792
|
err.data.retryAfter = retryAfter;
|
|
6757
6793
|
}
|
|
6758
6794
|
function describeRetry(retryAfter, retryAfterMs) {
|
|
6759
|
-
if (retryAfterMs !== void 0) return `The server asked to retry after ${formatDuration(retryAfterMs)}.`;
|
|
6795
|
+
if (retryAfterMs !== void 0) return `The server asked to retry after ${formatDuration$1(retryAfterMs)}.`;
|
|
6760
6796
|
if (retryAfter !== void 0) return `The server sent an unparseable Retry-After (${retryAfter}).`;
|
|
6761
6797
|
return "The server sent no Retry-After header.";
|
|
6762
6798
|
}
|
|
@@ -6801,8 +6837,7 @@ function applyAuthorizationParams(authorizationUrl, params) {
|
|
|
6801
6837
|
for (const [key, value] of applicable) merged.searchParams.set(key.trim(), value);
|
|
6802
6838
|
return merged;
|
|
6803
6839
|
}
|
|
6804
|
-
|
|
6805
|
-
//#region ../../core/auth/scopes.ts
|
|
6840
|
+
// ../../core/auth/scopes.ts
|
|
6806
6841
|
const computeScopeUnion$1 = computeScopeUnion;
|
|
6807
6842
|
const isStrictScopeSuperset$1 = isStrictScopeSuperset;
|
|
6808
6843
|
const OFFLINE_ACCESS_SCOPE = "offline_access";
|
|
@@ -6830,8 +6865,7 @@ function resolveEffectiveGrantedScope(storedScope, tokenScope) {
|
|
|
6830
6865
|
if (granted) return granted;
|
|
6831
6866
|
return computeScopeUnion$1(storedScope, tokenScope);
|
|
6832
6867
|
}
|
|
6833
|
-
|
|
6834
|
-
//#region ../../core/auth/providers.ts
|
|
6868
|
+
// ../../core/auth/providers.ts
|
|
6835
6869
|
var MutableRedirectUrlProvider = class {
|
|
6836
6870
|
redirectUrl = "";
|
|
6837
6871
|
getRedirectUrl() {
|
|
@@ -7062,8 +7096,7 @@ var BaseOAuthClientProvider = class {
|
|
|
7062
7096
|
}
|
|
7063
7097
|
}
|
|
7064
7098
|
};
|
|
7065
|
-
|
|
7066
|
-
//#region ../../core/auth/types.ts
|
|
7099
|
+
// ../../core/auth/types.ts
|
|
7067
7100
|
function authProtocolFromEnterpriseManaged(enterpriseManaged) {
|
|
7068
7101
|
return enterpriseManaged ? "ema" : "standard";
|
|
7069
7102
|
}
|
|
@@ -7084,8 +7117,7 @@ const EMPTY_OAUTH_FLOW_STATE = {
|
|
|
7084
7117
|
statusMessage: null,
|
|
7085
7118
|
validationError: null
|
|
7086
7119
|
};
|
|
7087
|
-
|
|
7088
|
-
//#region ../../core/auth/mcpAuth.ts
|
|
7120
|
+
// ../../core/auth/mcpAuth.ts
|
|
7089
7121
|
async function mcpAuth(provider, options) {
|
|
7090
7122
|
if (options.forceReauthorization && options.authorizationCode !== void 0) throw new Error("forceReauthorization cannot be combined with authorizationCode");
|
|
7091
7123
|
return auth(provider, {
|
|
@@ -7356,8 +7388,7 @@ async function runPlan(plan, params) {
|
|
|
7356
7388
|
}
|
|
7357
7389
|
return aggregateOutcomes(outcomes);
|
|
7358
7390
|
}
|
|
7359
|
-
|
|
7360
|
-
//#region ../../core/auth/ema/clientConfigError.ts
|
|
7391
|
+
// ../../core/auth/ema/clientConfigError.ts
|
|
7361
7392
|
function emaClientNotConfiguredMessage(reason) {
|
|
7362
7393
|
if (reason === "disabled") return "This server uses enterprise-managed authorization, but Enterprise IdP is turned off in Client Settings. Open Client Settings, enable \"Enterprise IdP configuration\", then try connecting again.";
|
|
7363
7394
|
return "This server uses enterprise-managed authorization, but the Inspector client IdP is not configured. Open Client Settings, enable Enterprise IdP, and set issuer, client ID, and client secret.";
|
|
@@ -7373,12 +7404,10 @@ var EmaClientNotConfiguredError = class extends Error {
|
|
|
7373
7404
|
function isEmaClientNotConfiguredError(err) {
|
|
7374
7405
|
return err instanceof EmaClientNotConfiguredError;
|
|
7375
7406
|
}
|
|
7376
|
-
|
|
7377
|
-
//#region ../../core/auth/ema/constants.ts
|
|
7407
|
+
// ../../core/auth/ema/constants.ts
|
|
7378
7408
|
const GRANT_TYPE_JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
7379
7409
|
const IDP_OIDC_SCOPES = "openid offline_access";
|
|
7380
|
-
|
|
7381
|
-
//#region ../../core/auth/ema/jwt.ts
|
|
7410
|
+
// ../../core/auth/ema/jwt.ts
|
|
7382
7411
|
function decodeBase64Url(segment) {
|
|
7383
7412
|
const base64 = segment.replace(/-/g, "+").replace(/_/g, "/");
|
|
7384
7413
|
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
@@ -7405,8 +7434,19 @@ function isJwtFormat(token) {
|
|
|
7405
7434
|
const parts = token.split(".");
|
|
7406
7435
|
return parts.length === 3 && parts[0].length > 0 && parts[1].length > 0 && parts[2] !== void 0;
|
|
7407
7436
|
}
|
|
7408
|
-
|
|
7409
|
-
|
|
7437
|
+
function decodeJwtPayload(token) {
|
|
7438
|
+
if (!isJwtFormat(token)) return void 0;
|
|
7439
|
+
const parts = token.split(".");
|
|
7440
|
+
try {
|
|
7441
|
+
return {
|
|
7442
|
+
header: JSON.parse(decodeBase64Url(parts[0])),
|
|
7443
|
+
payload: JSON.parse(decodeBase64Url(parts[1]))
|
|
7444
|
+
};
|
|
7445
|
+
} catch {
|
|
7446
|
+
return;
|
|
7447
|
+
}
|
|
7448
|
+
}
|
|
7449
|
+
// ../../core/auth/ema/storage.ts
|
|
7410
7450
|
function normalizeIdpIssuer(issuer) {
|
|
7411
7451
|
return issuer.replace(/\/$/, "");
|
|
7412
7452
|
}
|
|
@@ -7414,8 +7454,7 @@ const IDP_OAUTH_KEY_PREFIX = "ema-idp:";
|
|
|
7414
7454
|
function idpOAuthStorageKey(issuer) {
|
|
7415
7455
|
return `${IDP_OAUTH_KEY_PREFIX}${normalizeIdpIssuer(issuer)}`;
|
|
7416
7456
|
}
|
|
7417
|
-
|
|
7418
|
-
//#region ../../core/auth/ema/tokenEndpoint.ts
|
|
7457
|
+
// ../../core/auth/ema/tokenEndpoint.ts
|
|
7419
7458
|
async function parseOAuthTokenErrorResponse(response, step) {
|
|
7420
7459
|
let body;
|
|
7421
7460
|
try {
|
|
@@ -7459,8 +7498,7 @@ async function postOAuthTokenRequest(tokenUrl, body, metadata, clientInformation
|
|
|
7459
7498
|
body
|
|
7460
7499
|
});
|
|
7461
7500
|
}
|
|
7462
|
-
|
|
7463
|
-
//#region ../../core/auth/ema/idpOidc.ts
|
|
7501
|
+
// ../../core/auth/ema/idpOidc.ts
|
|
7464
7502
|
function idpClientInformation(idp) {
|
|
7465
7503
|
return {
|
|
7466
7504
|
client_id: idp.clientId,
|
|
@@ -7583,8 +7621,7 @@ async function getValidIdToken(params) {
|
|
|
7583
7621
|
return;
|
|
7584
7622
|
}
|
|
7585
7623
|
}
|
|
7586
|
-
|
|
7587
|
-
//#region ../../core/auth/discovery.ts
|
|
7624
|
+
// ../../core/auth/discovery.ts
|
|
7588
7625
|
function serverUrlAsAuthorizationServer(serverUrl) {
|
|
7589
7626
|
try {
|
|
7590
7627
|
const url = new URL(serverUrl);
|
|
@@ -7626,8 +7663,7 @@ async function discoverAuthorizationServerMetadataFromCandidates(candidates, dis
|
|
|
7626
7663
|
async function discoverAuthorizationServerMetadataForServer(serverUrl, resourceMetadata, fetchFn) {
|
|
7627
7664
|
return (await discoverAuthorizationServerMetadataFromCandidates(getAuthorizationServerUrlCandidates(serverUrl, resourceMetadata), (candidate) => discoverAuthorizationServerMetadata(candidate, { fetchFn })))?.metadata;
|
|
7628
7665
|
}
|
|
7629
|
-
|
|
7630
|
-
//#region ../../core/auth/ema/resourceContext.ts
|
|
7666
|
+
// ../../core/auth/ema/resourceContext.ts
|
|
7631
7667
|
function resolveEmaScopes(resourceMetadata, configuredScope) {
|
|
7632
7668
|
const trimmed = configuredScope?.trim();
|
|
7633
7669
|
if (trimmed) return trimmed;
|
|
@@ -7660,8 +7696,7 @@ async function discoverResourceAsMetadata(resourceAsUrl, fetchFn) {
|
|
|
7660
7696
|
if (!metadata) throw new Error("Failed to discover resource authorization server metadata");
|
|
7661
7697
|
return metadata;
|
|
7662
7698
|
}
|
|
7663
|
-
|
|
7664
|
-
//#region ../../core/auth/ema/wire.ts
|
|
7699
|
+
// ../../core/auth/ema/wire.ts
|
|
7665
7700
|
async function exchangeIdJag(params) {
|
|
7666
7701
|
const issuer = normalizeIdpIssuer(params.idp.issuer);
|
|
7667
7702
|
const resource = params.resource.trim();
|
|
@@ -7705,8 +7740,7 @@ async function redeemIdJagForAccessToken(params) {
|
|
|
7705
7740
|
if (!response.ok) throw await parseOAuthTokenErrorResponse(response, "EMA leg 3 (resource AS JWT bearer grant)");
|
|
7706
7741
|
return OAuthTokensSchema.parse(await response.json());
|
|
7707
7742
|
}
|
|
7708
|
-
|
|
7709
|
-
//#region ../../core/auth/ema/emaFlow.ts
|
|
7743
|
+
// ../../core/auth/ema/emaFlow.ts
|
|
7710
7744
|
function wrapEmaMintError(err) {
|
|
7711
7745
|
const message = err instanceof Error ? err.message : String(err);
|
|
7712
7746
|
return new Error(`EMA legs 2–3 (resource token mint): ${message}`, { cause: err });
|
|
@@ -7806,8 +7840,7 @@ async function refreshEmaResourceTokens(config) {
|
|
|
7806
7840
|
await saveMintedTokens(config, minted);
|
|
7807
7841
|
return minted.tokens;
|
|
7808
7842
|
}
|
|
7809
|
-
|
|
7810
|
-
//#region ../../core/auth/ema/idpSession.ts
|
|
7843
|
+
// ../../core/auth/ema/idpSession.ts
|
|
7811
7844
|
async function getEmaIdpLoginState(storage, issuer) {
|
|
7812
7845
|
const normalized = normalizeIdpIssuer(issuer);
|
|
7813
7846
|
if (!normalized) return "none";
|
|
@@ -7817,8 +7850,7 @@ async function getEmaIdpLoginState(storage, issuer) {
|
|
|
7817
7850
|
if (session.refreshToken) return "logged_in";
|
|
7818
7851
|
return "expired";
|
|
7819
7852
|
}
|
|
7820
|
-
|
|
7821
|
-
//#region ../../core/auth/connection-state.ts
|
|
7853
|
+
// ../../core/auth/connection-state.ts
|
|
7822
7854
|
function isAccessTokenUsable$1(tokens) {
|
|
7823
7855
|
if (!tokens?.access_token) return false;
|
|
7824
7856
|
return !isJwtExpired(tokens.access_token);
|
|
@@ -7901,8 +7933,7 @@ async function hasPersistedOAuthServerState(storage, serverUrl) {
|
|
|
7901
7933
|
function protocolFromOAuthConfig(config) {
|
|
7902
7934
|
return authProtocolFromEnterpriseManaged(config.enterpriseManaged);
|
|
7903
7935
|
}
|
|
7904
|
-
|
|
7905
|
-
//#region ../../core/auth/cimd.ts
|
|
7936
|
+
// ../../core/auth/cimd.ts
|
|
7906
7937
|
async function ensureCimdClientRegistration(params) {
|
|
7907
7938
|
const clientMetadataUrl = params.provider.clientMetadataUrl?.trim();
|
|
7908
7939
|
if (!clientMetadataUrl) return;
|
|
@@ -7928,8 +7959,7 @@ async function ensureCimdClientRegistration(params) {
|
|
|
7928
7959
|
...issuer && { issuer }
|
|
7929
7960
|
});
|
|
7930
7961
|
}
|
|
7931
|
-
|
|
7932
|
-
//#region ../../core/auth/ema/transportProvider.ts
|
|
7962
|
+
// ../../core/auth/ema/transportProvider.ts
|
|
7933
7963
|
function isAccessTokenUsable(tokens, skewMs = 6e4) {
|
|
7934
7964
|
if (!tokens.access_token) return false;
|
|
7935
7965
|
return !isJwtExpired(tokens.access_token, skewMs);
|
|
@@ -7989,8 +8019,7 @@ var EmaTransportOAuthProvider = class {
|
|
|
7989
8019
|
return this.inner.codeVerifier();
|
|
7990
8020
|
}
|
|
7991
8021
|
};
|
|
7992
|
-
|
|
7993
|
-
//#region ../../core/auth/oauthUx.ts
|
|
8022
|
+
// ../../core/auth/oauthUx.ts
|
|
7994
8023
|
function isStandardOAuthStepUp(challenge, options) {
|
|
7995
8024
|
return challenge.reason === "insufficient_scope" && !options?.enterpriseManaged;
|
|
7996
8025
|
}
|
|
@@ -8062,8 +8091,7 @@ function issuerBindingFailureCopy(failure, options) {
|
|
|
8062
8091
|
})
|
|
8063
8092
|
};
|
|
8064
8093
|
}
|
|
8065
|
-
|
|
8066
|
-
//#region ../../core/mcp/oauthManager.ts
|
|
8094
|
+
// ../../core/mcp/oauthManager.ts
|
|
8067
8095
|
var OAuthManager = class {
|
|
8068
8096
|
params;
|
|
8069
8097
|
oauthConfig;
|
|
@@ -8546,8 +8574,7 @@ var OAuthManager = class {
|
|
|
8546
8574
|
return provider;
|
|
8547
8575
|
}
|
|
8548
8576
|
};
|
|
8549
|
-
|
|
8550
|
-
//#region ../../core/mcp/remote/types.ts
|
|
8577
|
+
// ../../core/mcp/remote/types.ts
|
|
8551
8578
|
function oauthTokensToRemoteAuthState(tokens) {
|
|
8552
8579
|
return { oauthTokens: {
|
|
8553
8580
|
access_token: tokens.access_token,
|
|
@@ -8558,8 +8585,7 @@ function oauthTokensToRemoteAuthState(tokens) {
|
|
|
8558
8585
|
id_token: tokens.id_token
|
|
8559
8586
|
} };
|
|
8560
8587
|
}
|
|
8561
|
-
|
|
8562
|
-
//#region ../../core/mcp/remote/progressToken.ts
|
|
8588
|
+
// ../../core/mcp/remote/progressToken.ts
|
|
8563
8589
|
function progressTokenOf(message) {
|
|
8564
8590
|
if ("method" in message && message.method === "notifications/progress" && "params" in message && typeof message.params === "object" && message.params !== null) {
|
|
8565
8591
|
const parsed = ProgressTokenSchema.safeParse(message.params.progressToken);
|
|
@@ -8572,8 +8598,7 @@ function waitForProgressToken(waits, token) {
|
|
|
8572
8598
|
const numeric = Number(token);
|
|
8573
8599
|
return Number.isSafeInteger(numeric) ? waits.get(numeric) : void 0;
|
|
8574
8600
|
}
|
|
8575
|
-
|
|
8576
|
-
//#region ../../core/mcp/remote/remoteClientTransport.ts
|
|
8601
|
+
// ../../core/mcp/remote/remoteClientTransport.ts
|
|
8577
8602
|
const DEFAULT_SSE_RESPONSE_TIMEOUT_MS = 6e4;
|
|
8578
8603
|
function requestIdForMessage(message) {
|
|
8579
8604
|
if ("method" in message && "id" in message && message.id !== null && message.id !== void 0) {
|
|
@@ -8717,7 +8742,8 @@ var RemoteClientTransport = class {
|
|
|
8717
8742
|
const body = {
|
|
8718
8743
|
config: this.config,
|
|
8719
8744
|
...authState && { authState },
|
|
8720
|
-
...this.options.settings && { settings: this.options.settings }
|
|
8745
|
+
...this.options.settings && { settings: this.options.settings },
|
|
8746
|
+
...this.options.serverName && { serverName: this.options.serverName }
|
|
8721
8747
|
};
|
|
8722
8748
|
const res = await this.fetchFn(`${this.baseUrl}/api/mcp/connect`, {
|
|
8723
8749
|
method: "POST",
|
|
@@ -9003,8 +9029,25 @@ var RemoteClientTransport = class {
|
|
|
9003
9029
|
onerror;
|
|
9004
9030
|
onmessage;
|
|
9005
9031
|
};
|
|
9006
|
-
|
|
9007
|
-
|
|
9032
|
+
// ../../core/mcp/sessionTermination.ts
|
|
9033
|
+
function canTerminateSession(transport) {
|
|
9034
|
+
return typeof transport === "object" && transport !== null && "terminateSession" in transport && typeof transport.terminateSession === "function";
|
|
9035
|
+
}
|
|
9036
|
+
const SESSION_TERMINATE_TIMEOUT_MS = 3e3;
|
|
9037
|
+
async function terminateSessionBestEffort(transport, timeoutMs = SESSION_TERMINATE_TIMEOUT_MS) {
|
|
9038
|
+
if (!canTerminateSession(transport) || !transport.sessionId) return false;
|
|
9039
|
+
let timer;
|
|
9040
|
+
const timedOut = new Promise((resolve) => {
|
|
9041
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
9042
|
+
});
|
|
9043
|
+
const terminated = new Promise((resolve) => resolve(transport.terminateSession())).then(() => true, () => false);
|
|
9044
|
+
try {
|
|
9045
|
+
return await Promise.race([terminated, timedOut]);
|
|
9046
|
+
} finally {
|
|
9047
|
+
clearTimeout(timer);
|
|
9048
|
+
}
|
|
9049
|
+
}
|
|
9050
|
+
// ../../core/mcp/inspectorClient.ts
|
|
9008
9051
|
const corePackageJson = {
|
|
9009
9052
|
name: "mcp-inspector",
|
|
9010
9053
|
version: "0.0.0"
|
|
@@ -9133,6 +9176,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9133
9176
|
transportClientFactory;
|
|
9134
9177
|
fetchFn;
|
|
9135
9178
|
effectiveAuthFetch;
|
|
9179
|
+
fetchRefusals = [];
|
|
9136
9180
|
sessionId;
|
|
9137
9181
|
transportConfig;
|
|
9138
9182
|
directAuthRecoveryActive = null;
|
|
@@ -9168,8 +9212,9 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9168
9212
|
resources: options.listChangedNotifications?.resources ?? true,
|
|
9169
9213
|
prompts: options.listChangedNotifications?.prompts ?? true
|
|
9170
9214
|
};
|
|
9171
|
-
const
|
|
9172
|
-
const
|
|
9215
|
+
const reportRefusal = (refusal) => this.recordFetchRefusal(refusal);
|
|
9216
|
+
const transportBase = withFetchRefusalReporting(this.fetchFn ?? fetch, reportRefusal);
|
|
9217
|
+
const oauthBase = options.environment.oauthFetch && withFetchRefusalReporting(options.environment.oauthFetch, reportRefusal);
|
|
9173
9218
|
const isMcpEndpoint = exemptMcpEndpoint(() => this.getServerUrl(), () => this.transportConfig?.type === "sse");
|
|
9174
9219
|
const getOverrides = () => this.oauthManager?.getEndpointOverrides();
|
|
9175
9220
|
const withOverrides = withOAuthEndpointOverrides(oauthBase ? routeOAuthRequests(transportBase, oauthBase, isMcpEndpoint) : transportBase, getOverrides);
|
|
@@ -9706,6 +9751,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9706
9751
|
while (handlers?.size !== void 0 && handlers.size > 0 && Date.now() < deadline) await new Promise((r) => setTimeout(r, 10));
|
|
9707
9752
|
}
|
|
9708
9753
|
await this.closeTaskSessionBestEffort();
|
|
9754
|
+
await terminateSessionBestEffort(this.baseTransport);
|
|
9709
9755
|
try {
|
|
9710
9756
|
await this.client.close();
|
|
9711
9757
|
} catch {}
|
|
@@ -9748,6 +9794,14 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
9748
9794
|
this.dispatchTypedEvent("excludedToolsChange", this.excludedTools);
|
|
9749
9795
|
this.dispatchTypedEvent("malformedListItemsChange", []);
|
|
9750
9796
|
}
|
|
9797
|
+
getFetchRefusals() {
|
|
9798
|
+
return [...this.fetchRefusals];
|
|
9799
|
+
}
|
|
9800
|
+
recordFetchRefusal(refusal) {
|
|
9801
|
+
if (this.fetchRefusals.some((r) => r.url === refusal.url && r.reason === refusal.reason)) return;
|
|
9802
|
+
this.fetchRefusals = [...this.fetchRefusals, refusal].slice(-20);
|
|
9803
|
+
this.dispatchTypedEvent("fetchRefused", refusal);
|
|
9804
|
+
}
|
|
9751
9805
|
getAppRendererClient() {
|
|
9752
9806
|
if (!this.client || this.status !== "connected") return null;
|
|
9753
9807
|
return this.client;
|
|
@@ -11400,8 +11454,7 @@ var InspectorClient = class InspectorClient extends InspectorClientEventTarget {
|
|
|
11400
11454
|
return this.oauthManager.getOAuthState();
|
|
11401
11455
|
}
|
|
11402
11456
|
};
|
|
11403
|
-
|
|
11404
|
-
//#region ../../core/mcp/state/managedListState.ts
|
|
11457
|
+
// ../../core/mcp/state/managedListState.ts
|
|
11405
11458
|
var ManagedListState = class extends TypedEventTarget {
|
|
11406
11459
|
items = [];
|
|
11407
11460
|
client = null;
|
|
@@ -11546,8 +11599,7 @@ var ManagedListState = class extends TypedEventTarget {
|
|
|
11546
11599
|
this.loaded = false;
|
|
11547
11600
|
}
|
|
11548
11601
|
};
|
|
11549
|
-
|
|
11550
|
-
//#region ../../core/mcp/state/managedToolsState.ts
|
|
11602
|
+
// ../../core/mcp/state/managedToolsState.ts
|
|
11551
11603
|
var ManagedToolsState = class extends ManagedListState {
|
|
11552
11604
|
constructor(client, debounceMs = 250) {
|
|
11553
11605
|
super(client, {
|
|
@@ -11570,8 +11622,7 @@ var ManagedToolsState = class extends ManagedListState {
|
|
|
11570
11622
|
return this.getItems();
|
|
11571
11623
|
}
|
|
11572
11624
|
};
|
|
11573
|
-
|
|
11574
|
-
//#region ../../core/mcp/state/messageLogState.ts
|
|
11625
|
+
// ../../core/mcp/state/messageLogState.ts
|
|
11575
11626
|
var MessageLogState = class extends TypedEventTarget {
|
|
11576
11627
|
messages = [];
|
|
11577
11628
|
pendingRequestEntries = /* @__PURE__ */ new Map();
|
|
@@ -11588,6 +11639,16 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
11588
11639
|
this.dispatchTypedEvent("message", entry);
|
|
11589
11640
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
11590
11641
|
};
|
|
11642
|
+
const replaceEntry = (entry, changes) => {
|
|
11643
|
+
const index = this.messages.lastIndexOf(entry);
|
|
11644
|
+
if (index < 0) return void 0;
|
|
11645
|
+
const updated = {
|
|
11646
|
+
...entry,
|
|
11647
|
+
...changes
|
|
11648
|
+
};
|
|
11649
|
+
this.messages[index] = updated;
|
|
11650
|
+
return updated;
|
|
11651
|
+
};
|
|
11591
11652
|
const onMessage = (event) => {
|
|
11592
11653
|
const entry = event.detail;
|
|
11593
11654
|
if (entry.direction === "request") {
|
|
@@ -11601,9 +11662,12 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
11601
11662
|
const requestEntry = messageId !== void 0 ? this.pendingRequestEntries.get(messageId) : void 0;
|
|
11602
11663
|
if (requestEntry) {
|
|
11603
11664
|
this.pendingRequestEntries.delete(messageId);
|
|
11604
|
-
|
|
11605
|
-
|
|
11606
|
-
|
|
11665
|
+
const updated = replaceEntry(requestEntry, {
|
|
11666
|
+
response: entry.message,
|
|
11667
|
+
duration: entry.timestamp.getTime() - requestEntry.timestamp.getTime()
|
|
11668
|
+
});
|
|
11669
|
+
if (!updated) return;
|
|
11670
|
+
this.dispatchTypedEvent("message", updated);
|
|
11607
11671
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
11608
11672
|
return;
|
|
11609
11673
|
}
|
|
@@ -11617,8 +11681,12 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
11617
11681
|
if (entry.message.id !== id) continue;
|
|
11618
11682
|
if (entry.direction === "notification") continue;
|
|
11619
11683
|
if (entry.direction === "request" && !entry.response) continue;
|
|
11620
|
-
|
|
11621
|
-
|
|
11684
|
+
const updated = {
|
|
11685
|
+
...entry,
|
|
11686
|
+
clientError: reason
|
|
11687
|
+
};
|
|
11688
|
+
this.messages[i] = updated;
|
|
11689
|
+
this.dispatchTypedEvent("message", updated);
|
|
11622
11690
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
11623
11691
|
return;
|
|
11624
11692
|
}
|
|
@@ -11628,9 +11696,12 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
11628
11696
|
const requestEntry = this.pendingRequestEntries.get(id);
|
|
11629
11697
|
if (!requestEntry) return;
|
|
11630
11698
|
this.pendingRequestEntries.delete(id);
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11699
|
+
const updated = replaceEntry(requestEntry, {
|
|
11700
|
+
clientError: reason,
|
|
11701
|
+
duration: Date.now() - requestEntry.timestamp.getTime()
|
|
11702
|
+
});
|
|
11703
|
+
if (!updated) return;
|
|
11704
|
+
this.dispatchTypedEvent("message", updated);
|
|
11634
11705
|
this.dispatchTypedEvent("messagesChange", this.getMessages());
|
|
11635
11706
|
};
|
|
11636
11707
|
const onStatusChange = () => {
|
|
@@ -11674,8 +11745,7 @@ var MessageLogState = class extends TypedEventTarget {
|
|
|
11674
11745
|
this.pendingRequestEntries.clear();
|
|
11675
11746
|
}
|
|
11676
11747
|
};
|
|
11677
|
-
|
|
11678
|
-
//#region ../../core/mcp/state/fetchRequestLogState.ts
|
|
11748
|
+
// ../../core/mcp/state/fetchRequestLogState.ts
|
|
11679
11749
|
var FetchRequestLogState = class extends TypedEventTarget {
|
|
11680
11750
|
fetchRequests = [];
|
|
11681
11751
|
client = null;
|
|
@@ -11794,8 +11864,7 @@ var FetchRequestLogState = class extends TypedEventTarget {
|
|
|
11794
11864
|
this.fetchRequests = [];
|
|
11795
11865
|
}
|
|
11796
11866
|
};
|
|
11797
|
-
|
|
11798
|
-
//#region ../../core/mcp/state/stderrLogState.ts
|
|
11867
|
+
// ../../core/mcp/state/stderrLogState.ts
|
|
11799
11868
|
var StderrLogState = class extends TypedEventTarget {
|
|
11800
11869
|
stderrLogs = [];
|
|
11801
11870
|
client = null;
|
|
@@ -11832,8 +11901,7 @@ var StderrLogState = class extends TypedEventTarget {
|
|
|
11832
11901
|
this.stderrLogs = [];
|
|
11833
11902
|
}
|
|
11834
11903
|
};
|
|
11835
|
-
|
|
11836
|
-
//#region ../../core/mcp/state/managedResourcesState.ts
|
|
11904
|
+
// ../../core/mcp/state/managedResourcesState.ts
|
|
11837
11905
|
var ManagedResourcesState = class extends ManagedListState {
|
|
11838
11906
|
constructor(client, debounceMs = 250) {
|
|
11839
11907
|
super(client, {
|
|
@@ -11856,8 +11924,7 @@ var ManagedResourcesState = class extends ManagedListState {
|
|
|
11856
11924
|
return this.getItems();
|
|
11857
11925
|
}
|
|
11858
11926
|
};
|
|
11859
|
-
|
|
11860
|
-
//#region ../../core/mcp/state/managedResourceTemplatesState.ts
|
|
11927
|
+
// ../../core/mcp/state/managedResourceTemplatesState.ts
|
|
11861
11928
|
var ManagedResourceTemplatesState = class extends ManagedListState {
|
|
11862
11929
|
constructor(client, debounceMs = 250) {
|
|
11863
11930
|
super(client, {
|
|
@@ -11880,8 +11947,7 @@ var ManagedResourceTemplatesState = class extends ManagedListState {
|
|
|
11880
11947
|
return this.getItems();
|
|
11881
11948
|
}
|
|
11882
11949
|
};
|
|
11883
|
-
|
|
11884
|
-
//#region ../../core/mcp/state/managedPromptsState.ts
|
|
11950
|
+
// ../../core/mcp/state/managedPromptsState.ts
|
|
11885
11951
|
var ManagedPromptsState = class extends ManagedListState {
|
|
11886
11952
|
constructor(client, debounceMs = 250) {
|
|
11887
11953
|
super(client, {
|
|
@@ -11904,8 +11970,7 @@ var ManagedPromptsState = class extends ManagedListState {
|
|
|
11904
11970
|
return this.getItems();
|
|
11905
11971
|
}
|
|
11906
11972
|
};
|
|
11907
|
-
|
|
11908
|
-
//#region ../../core/mcp/state/mergeTaskIntoList.ts
|
|
11973
|
+
// ../../core/mcp/state/mergeTaskIntoList.ts
|
|
11909
11974
|
function mergeTaskIntoList(tasks, taskId, task) {
|
|
11910
11975
|
const normalized = {
|
|
11911
11976
|
...task,
|
|
@@ -11918,8 +11983,7 @@ function mergeTaskIntoList(tasks, taskId, task) {
|
|
|
11918
11983
|
next[idx] = normalized;
|
|
11919
11984
|
return next;
|
|
11920
11985
|
}
|
|
11921
|
-
|
|
11922
|
-
//#region ../../core/mcp/state/managedRequestorTasksState.ts
|
|
11986
|
+
// ../../core/mcp/state/managedRequestorTasksState.ts
|
|
11923
11987
|
const MAX_PAGES = 100;
|
|
11924
11988
|
const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
11925
11989
|
"completed",
|
|
@@ -12054,8 +12118,7 @@ var ManagedRequestorTasksState = class extends TypedEventTarget {
|
|
|
12054
12118
|
this.cancelledTaskIds.clear();
|
|
12055
12119
|
}
|
|
12056
12120
|
};
|
|
12057
|
-
|
|
12058
|
-
//#region ../../core/mcp/state/resourceSubscriptionsState.ts
|
|
12121
|
+
// ../../core/mcp/state/resourceSubscriptionsState.ts
|
|
12059
12122
|
var ResourceSubscriptionsState = class extends TypedEventTarget {
|
|
12060
12123
|
subscribedUris = [];
|
|
12061
12124
|
lastUpdatedByUri = /* @__PURE__ */ new Map();
|
|
@@ -12144,8 +12207,7 @@ var ResourceSubscriptionsState = class extends TypedEventTarget {
|
|
|
12144
12207
|
this.streamState = INACTIVE_SUBSCRIPTION_STREAM_STATE;
|
|
12145
12208
|
}
|
|
12146
12209
|
};
|
|
12147
|
-
|
|
12148
|
-
//#region ../../core/mcp/state/managedSkillsState.ts
|
|
12210
|
+
// ../../core/mcp/state/managedSkillsState.ts
|
|
12149
12211
|
const REPEATED_CURSOR_MESSAGE = "Server repeated a pagination cursor in skills/list; stopped to avoid an infinite walk.";
|
|
12150
12212
|
const SKILLS_MAX_PAGES = 64;
|
|
12151
12213
|
const SKILLS_PAGE_LIMIT_MESSAGE = `skills/list exceeded ${SKILLS_MAX_PAGES} pages without the server's pagination converging`;
|
|
@@ -12254,17 +12316,45 @@ var ManagedSkillsState = class extends TypedEventTarget {
|
|
|
12254
12316
|
this.error = null;
|
|
12255
12317
|
}
|
|
12256
12318
|
};
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12319
|
+
// ../../core/react/notifyScheduler.ts
|
|
12320
|
+
function coalesce(onChange, schedule) {
|
|
12321
|
+
let cancelPending = null;
|
|
12322
|
+
return {
|
|
12323
|
+
notify: () => {
|
|
12324
|
+
if (cancelPending) return;
|
|
12325
|
+
cancelPending = schedule(() => {
|
|
12326
|
+
cancelPending = null;
|
|
12327
|
+
onChange();
|
|
12328
|
+
});
|
|
12329
|
+
},
|
|
12330
|
+
cancel: () => {
|
|
12331
|
+
cancelPending?.();
|
|
12332
|
+
cancelPending = null;
|
|
12333
|
+
}
|
|
12334
|
+
};
|
|
12335
|
+
}
|
|
12336
|
+
// ../../core/react/useStoreSnapshot.ts
|
|
12337
|
+
function useStoreSnapshot(store, event, read, whenAbsent, schedule) {
|
|
12260
12338
|
const cache = useRef(null);
|
|
12261
12339
|
const subscribe = useCallback((onStoreChange) => {
|
|
12262
12340
|
if (!store) return () => {};
|
|
12263
|
-
|
|
12341
|
+
if (!schedule) {
|
|
12342
|
+
store.addEventListener(event, onStoreChange);
|
|
12343
|
+
return () => {
|
|
12344
|
+
store.removeEventListener(event, onStoreChange);
|
|
12345
|
+
};
|
|
12346
|
+
}
|
|
12347
|
+
const { notify, cancel } = coalesce(onStoreChange, schedule);
|
|
12348
|
+
store.addEventListener(event, notify);
|
|
12264
12349
|
return () => {
|
|
12265
|
-
store.removeEventListener(event,
|
|
12350
|
+
store.removeEventListener(event, notify);
|
|
12351
|
+
cancel();
|
|
12266
12352
|
};
|
|
12267
|
-
}, [
|
|
12353
|
+
}, [
|
|
12354
|
+
store,
|
|
12355
|
+
event,
|
|
12356
|
+
schedule
|
|
12357
|
+
]);
|
|
12268
12358
|
const getSnapshot = useCallback(() => {
|
|
12269
12359
|
const revision = store ? store.getEventRevision(event) : 0;
|
|
12270
12360
|
const cached = cache.current;
|
|
@@ -12287,8 +12377,7 @@ function useStoreSnapshot(store, event, read, whenAbsent) {
|
|
|
12287
12377
|
]);
|
|
12288
12378
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
12289
12379
|
}
|
|
12290
|
-
|
|
12291
|
-
//#region ../../core/react/useInspectorClient.ts
|
|
12380
|
+
// ../../core/react/useInspectorClient.ts
|
|
12292
12381
|
const EMPTY_CLIENT_CAPABILITIES = Object.freeze({});
|
|
12293
12382
|
const NO_EXCLUDED_TOOLS = [];
|
|
12294
12383
|
const NO_MALFORMED_LIST_ITEMS = [];
|
|
@@ -12306,7 +12395,7 @@ const readDiscoverResult = (client) => client.getDiscoverResult();
|
|
|
12306
12395
|
const readExcludedTools = (client) => client.getExcludedTools();
|
|
12307
12396
|
const readMalformedListItems = (client) => client.getMalformedListItems();
|
|
12308
12397
|
const readConnectionDiagnostics = (client) => client.getConnectionDiagnostics?.() ?? NO_CONNECTION_DIAGNOSTICS;
|
|
12309
|
-
function useInspectorClient(inspectorClient) {
|
|
12398
|
+
function useInspectorClient(inspectorClient, diagnosticsSchedule) {
|
|
12310
12399
|
const status = useStoreSnapshot(inspectorClient, "statusChange", readStatus, "disconnected");
|
|
12311
12400
|
const capabilities = useStoreSnapshot(inspectorClient, "capabilitiesChange", readCapabilities, void 0);
|
|
12312
12401
|
const serverInfo = useStoreSnapshot(inspectorClient, "serverInfoChange", readServerInfo, void 0);
|
|
@@ -12316,7 +12405,7 @@ function useInspectorClient(inspectorClient) {
|
|
|
12316
12405
|
const discoverResult = useStoreSnapshot(inspectorClient, "discoverResultChange", readDiscoverResult, void 0);
|
|
12317
12406
|
const excludedTools = useStoreSnapshot(inspectorClient, "excludedToolsChange", readExcludedTools, NO_EXCLUDED_TOOLS);
|
|
12318
12407
|
const malformedListItems = useStoreSnapshot(inspectorClient, "malformedListItemsChange", readMalformedListItems, NO_MALFORMED_LIST_ITEMS);
|
|
12319
|
-
const connectionDiagnostics = useStoreSnapshot(inspectorClient, "connectionDiagnosticsChange", readConnectionDiagnostics, NO_CONNECTION_DIAGNOSTICS);
|
|
12408
|
+
const connectionDiagnostics = useStoreSnapshot(inspectorClient, "connectionDiagnosticsChange", readConnectionDiagnostics, NO_CONNECTION_DIAGNOSTICS, diagnosticsSchedule);
|
|
12320
12409
|
const [errorState, setErrorState] = useState({ client: inspectorClient });
|
|
12321
12410
|
if (errorState.client !== inspectorClient) setErrorState({ client: inspectorClient });
|
|
12322
12411
|
const lastError = errorState.client === inspectorClient ? errorState.message : void 0;
|
|
@@ -12364,8 +12453,7 @@ function useInspectorClient(inspectorClient) {
|
|
|
12364
12453
|
disconnect
|
|
12365
12454
|
};
|
|
12366
12455
|
}
|
|
12367
|
-
|
|
12368
|
-
//#region ../../core/react/useListError.ts
|
|
12456
|
+
// ../../core/react/useListError.ts
|
|
12369
12457
|
function useListError(state) {
|
|
12370
12458
|
const subscribe = useCallback((onStoreChange) => {
|
|
12371
12459
|
if (!state) return () => {};
|
|
@@ -12378,8 +12466,7 @@ function useListError(state) {
|
|
|
12378
12466
|
const getSnapshot = useCallback(() => state?.getError() ?? null, [state]);
|
|
12379
12467
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
12380
12468
|
}
|
|
12381
|
-
|
|
12382
|
-
//#region ../../core/react/useManagedTools.ts
|
|
12469
|
+
// ../../core/react/useManagedTools.ts
|
|
12383
12470
|
const NO_TOOLS = [];
|
|
12384
12471
|
const readTools = (state) => state.getTools();
|
|
12385
12472
|
const readListChanged$2 = (state) => state.getListChanged();
|
|
@@ -12403,8 +12490,7 @@ function useManagedTools(client, managedToolsState) {
|
|
|
12403
12490
|
}, [managedToolsState])
|
|
12404
12491
|
};
|
|
12405
12492
|
}
|
|
12406
|
-
|
|
12407
|
-
//#region ../../core/mcp/toolOrder.ts
|
|
12493
|
+
// ../../core/mcp/toolOrder.ts
|
|
12408
12494
|
const toolLabelCollator = new Intl.Collator(void 0, {
|
|
12409
12495
|
sensitivity: "base",
|
|
12410
12496
|
numeric: true
|
|
@@ -12415,8 +12501,7 @@ function compareToolLabels(a, b) {
|
|
|
12415
12501
|
function compareToolsByName(a, b) {
|
|
12416
12502
|
return compareToolLabels(a.name, b.name);
|
|
12417
12503
|
}
|
|
12418
|
-
|
|
12419
|
-
//#region ../../core/react/useManagedResources.ts
|
|
12504
|
+
// ../../core/react/useManagedResources.ts
|
|
12420
12505
|
const NO_RESOURCES = [];
|
|
12421
12506
|
const readResources = (state) => state.getResources();
|
|
12422
12507
|
const readListChanged$1 = (state) => state.getListChanged();
|
|
@@ -12440,8 +12525,7 @@ function useManagedResources(client, managedResourcesState) {
|
|
|
12440
12525
|
}, [managedResourcesState])
|
|
12441
12526
|
};
|
|
12442
12527
|
}
|
|
12443
|
-
|
|
12444
|
-
//#region ../../core/react/useManagedResourceTemplates.ts
|
|
12528
|
+
// ../../core/react/useManagedResourceTemplates.ts
|
|
12445
12529
|
const NO_RESOURCE_TEMPLATES = [];
|
|
12446
12530
|
const readResourceTemplates = (state) => state.getResourceTemplates();
|
|
12447
12531
|
function useManagedResourceTemplates(client, managedResourceTemplatesState) {
|
|
@@ -12454,8 +12538,7 @@ function useManagedResourceTemplates(client, managedResourceTemplatesState) {
|
|
|
12454
12538
|
}, [client, managedResourceTemplatesState])
|
|
12455
12539
|
};
|
|
12456
12540
|
}
|
|
12457
|
-
|
|
12458
|
-
//#region ../../core/react/useManagedPrompts.ts
|
|
12541
|
+
// ../../core/react/useManagedPrompts.ts
|
|
12459
12542
|
const NO_PROMPTS = [];
|
|
12460
12543
|
const readPrompts = (state) => state.getPrompts();
|
|
12461
12544
|
const readListChanged = (state) => state.getListChanged();
|
|
@@ -12479,8 +12562,7 @@ function useManagedPrompts(client, managedPromptsState) {
|
|
|
12479
12562
|
}, [managedPromptsState])
|
|
12480
12563
|
};
|
|
12481
12564
|
}
|
|
12482
|
-
|
|
12483
|
-
//#region ../../core/react/useManagedSkills.ts
|
|
12565
|
+
// ../../core/react/useManagedSkills.ts
|
|
12484
12566
|
const NO_SKILLS = [];
|
|
12485
12567
|
const NO_SKILLS_PAGINATION = Object.freeze({ pageCount: 0 });
|
|
12486
12568
|
const readSkills = (state) => state.getSkills();
|
|
@@ -12498,29 +12580,25 @@ function useManagedSkills(client, managedSkillsState) {
|
|
|
12498
12580
|
}, [client, managedSkillsState])
|
|
12499
12581
|
};
|
|
12500
12582
|
}
|
|
12501
|
-
|
|
12502
|
-
//#region ../../core/react/useMessageLog.ts
|
|
12583
|
+
// ../../core/react/useMessageLog.ts
|
|
12503
12584
|
const NO_MESSAGES = [];
|
|
12504
12585
|
const readMessages = (state) => state.getMessages();
|
|
12505
|
-
function useMessageLog(messageLogState) {
|
|
12506
|
-
return { messages: useStoreSnapshot(messageLogState, "messagesChange", readMessages, NO_MESSAGES) };
|
|
12586
|
+
function useMessageLog(messageLogState, schedule) {
|
|
12587
|
+
return { messages: useStoreSnapshot(messageLogState, "messagesChange", readMessages, NO_MESSAGES, schedule) };
|
|
12507
12588
|
}
|
|
12508
|
-
|
|
12509
|
-
//#region ../../core/react/useFetchRequestLog.ts
|
|
12589
|
+
// ../../core/react/useFetchRequestLog.ts
|
|
12510
12590
|
const NO_FETCH_REQUESTS = [];
|
|
12511
12591
|
const readFetchRequests = (state) => state.getFetchRequests();
|
|
12512
|
-
function useFetchRequestLog(fetchRequestLogState) {
|
|
12513
|
-
return { fetchRequests: useStoreSnapshot(fetchRequestLogState, "fetchRequestsChange", readFetchRequests, NO_FETCH_REQUESTS) };
|
|
12592
|
+
function useFetchRequestLog(fetchRequestLogState, schedule) {
|
|
12593
|
+
return { fetchRequests: useStoreSnapshot(fetchRequestLogState, "fetchRequestsChange", readFetchRequests, NO_FETCH_REQUESTS, schedule) };
|
|
12514
12594
|
}
|
|
12515
|
-
|
|
12516
|
-
//#region ../../core/react/useStderrLog.ts
|
|
12595
|
+
// ../../core/react/useStderrLog.ts
|
|
12517
12596
|
const NO_STDERR_LOGS = [];
|
|
12518
12597
|
const readStderrLogs = (state) => state.getStderrLogs();
|
|
12519
|
-
function useStderrLog(stderrLogState) {
|
|
12520
|
-
return { stderrLogs: useStoreSnapshot(stderrLogState, "stderrLogsChange", readStderrLogs, NO_STDERR_LOGS) };
|
|
12598
|
+
function useStderrLog(stderrLogState, schedule) {
|
|
12599
|
+
return { stderrLogs: useStoreSnapshot(stderrLogState, "stderrLogsChange", readStderrLogs, NO_STDERR_LOGS, schedule) };
|
|
12521
12600
|
}
|
|
12522
|
-
|
|
12523
|
-
//#region ../../core/react/useManagedRequestorTasks.ts
|
|
12601
|
+
// ../../core/react/useManagedRequestorTasks.ts
|
|
12524
12602
|
const NO_TASKS = [];
|
|
12525
12603
|
const readTasks = (state) => state.getTasks();
|
|
12526
12604
|
function useManagedRequestorTasks(client, managedRequestorTasksState) {
|
|
@@ -12535,8 +12613,7 @@ function useManagedRequestorTasks(client, managedRequestorTasksState) {
|
|
|
12535
12613
|
}, [managedRequestorTasksState])
|
|
12536
12614
|
};
|
|
12537
12615
|
}
|
|
12538
|
-
|
|
12539
|
-
//#region ../../core/react/useResourceSubscriptions.ts
|
|
12616
|
+
// ../../core/react/useResourceSubscriptions.ts
|
|
12540
12617
|
const NO_SUBSCRIPTIONS = [];
|
|
12541
12618
|
const readSubscriptions = (state) => state.getSubscriptions();
|
|
12542
12619
|
const readStreamState = (state) => state.getStreamState();
|
|
@@ -12546,8 +12623,18 @@ function useResourceSubscriptions(state) {
|
|
|
12546
12623
|
streamState: useStoreSnapshot(state, "streamStateChange", readStreamState, INACTIVE_SUBSCRIPTION_STREAM_STATE)
|
|
12547
12624
|
};
|
|
12548
12625
|
}
|
|
12549
|
-
|
|
12550
|
-
|
|
12626
|
+
// ../../core/react/usePendingClientRequests.ts
|
|
12627
|
+
const NO_SAMPLES = [];
|
|
12628
|
+
const NO_ELICITATIONS = [];
|
|
12629
|
+
const readPendingSamples = (client) => client.getPendingSamples();
|
|
12630
|
+
const readPendingElicitations = (client) => client.getPendingElicitations();
|
|
12631
|
+
function usePendingClientRequests(inspectorClient) {
|
|
12632
|
+
return {
|
|
12633
|
+
pendingSamples: useStoreSnapshot(inspectorClient, "pendingSamplesChange", readPendingSamples, NO_SAMPLES),
|
|
12634
|
+
pendingElicitations: useStoreSnapshot(inspectorClient, "pendingElicitationsChange", readPendingElicitations, NO_ELICITATIONS)
|
|
12635
|
+
};
|
|
12636
|
+
}
|
|
12637
|
+
// ../../core/auth/issuerBinding.ts
|
|
12551
12638
|
const MISSING_DISCOVERY_STATE_PHRASE = "discoveryState was not available";
|
|
12552
12639
|
function isAuthorizationServerMismatchShape(err) {
|
|
12553
12640
|
if (err === null || typeof err !== "object") return false;
|
|
@@ -12587,8 +12674,7 @@ function classifyAuthorizationServerMismatch(err) {
|
|
|
12587
12674
|
currentIssuer: err.currentIssuer
|
|
12588
12675
|
};
|
|
12589
12676
|
}
|
|
12590
|
-
|
|
12591
|
-
//#region ../../core/auth/oauth-storage.ts
|
|
12677
|
+
// ../../core/auth/oauth-storage.ts
|
|
12592
12678
|
function withIssuer(value, issuer) {
|
|
12593
12679
|
return issuer === void 0 ? value : {
|
|
12594
12680
|
...value,
|
|
@@ -12865,8 +12951,7 @@ var OAuthStorageBase = class {
|
|
|
12865
12951
|
await this.persist({ servers });
|
|
12866
12952
|
}
|
|
12867
12953
|
};
|
|
12868
|
-
|
|
12869
|
-
//#region ../../core/auth/store.ts
|
|
12954
|
+
// ../../core/auth/store.ts
|
|
12870
12955
|
var OAuthMemoryStore = class {
|
|
12871
12956
|
servers = {};
|
|
12872
12957
|
idpSessions = {};
|
|
@@ -12929,8 +13014,7 @@ var OAuthMemoryStore = class {
|
|
|
12929
13014
|
this.idpSessions = { ...snapshot.idpSessions ?? {} };
|
|
12930
13015
|
}
|
|
12931
13016
|
};
|
|
12932
|
-
|
|
12933
|
-
//#region ../../core/auth/oauth-persist.ts
|
|
13017
|
+
// ../../core/auth/oauth-persist.ts
|
|
12934
13018
|
function mergeOAuthSections(disk, snapshot, sections) {
|
|
12935
13019
|
const merged = {
|
|
12936
13020
|
servers: { ...disk?.servers },
|
|
@@ -12995,8 +13079,7 @@ function parseOAuthPersistBlob(raw) {
|
|
|
12995
13079
|
function serializeOAuthPersistBlob(snapshot) {
|
|
12996
13080
|
return serializeStore(snapshot);
|
|
12997
13081
|
}
|
|
12998
|
-
|
|
12999
|
-
//#region ../../core/auth/node/oauth-secrets.ts
|
|
13082
|
+
// ../../core/auth/node/oauth-secrets.ts
|
|
13000
13083
|
const PERSIST_TOKENS_ENV = "MCP_INSPECTOR_PERSIST_TOKENS";
|
|
13001
13084
|
const warnedPolicyValues = /* @__PURE__ */ new Set();
|
|
13002
13085
|
function getPersistTokensPolicy(env = process.env) {
|
|
@@ -13266,8 +13349,7 @@ function snapshotHasPlaintextSecrets(snapshot) {
|
|
|
13266
13349
|
for (const session of Object.values(snapshot.idpSessions)) if (session.idToken !== void 0 || session.refreshToken !== void 0) return true;
|
|
13267
13350
|
return false;
|
|
13268
13351
|
}
|
|
13269
|
-
|
|
13270
|
-
//#region ../../core/auth/node/oauth-namespace-ledger.ts
|
|
13352
|
+
// ../../core/auth/node/oauth-namespace-ledger.ts
|
|
13271
13353
|
const namespaceLedgerPath = (stateFilePath) => `${stateFilePath}.namespaces.json`;
|
|
13272
13354
|
const KEYRING_LOCATION = "keyring";
|
|
13273
13355
|
const FILE_LOCATION_PREFIX = "file:";
|
|
@@ -13525,8 +13607,7 @@ async function purgeSupersededNamespaces(stateFilePath, secretStore, current, ow
|
|
|
13525
13607
|
warnLedgerFailure("update", error);
|
|
13526
13608
|
}
|
|
13527
13609
|
}
|
|
13528
|
-
|
|
13529
|
-
//#region ../../core/auth/node/oauth-persist-file.ts
|
|
13610
|
+
// ../../core/auth/node/oauth-persist-file.ts
|
|
13530
13611
|
const warnedStoreFailures = /* @__PURE__ */ new Set();
|
|
13531
13612
|
function warnStoreWriteFailure(error) {
|
|
13532
13613
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -14072,8 +14153,7 @@ function createFileOAuthPersistBackend(options) {
|
|
|
14072
14153
|
}
|
|
14073
14154
|
};
|
|
14074
14155
|
}
|
|
14075
|
-
|
|
14076
|
-
//#region ../../core/auth/node/storage-node.ts
|
|
14156
|
+
// ../../core/auth/node/storage-node.ts
|
|
14077
14157
|
const DEFAULT_STATE_PATH = getStoreFilePath(getDefaultStorageDir(), "oauth");
|
|
14078
14158
|
function getStateFilePath(customPath) {
|
|
14079
14159
|
if (customPath) return customPath;
|
|
@@ -14104,8 +14184,7 @@ var NodeOAuthStorage = class extends OAuthStorageBase {
|
|
|
14104
14184
|
}), shared.coordination);
|
|
14105
14185
|
}
|
|
14106
14186
|
};
|
|
14107
|
-
|
|
14108
|
-
//#region ../../core/auth/node/oauth-callback-server.ts
|
|
14187
|
+
// ../../core/auth/node/oauth-callback-server.ts
|
|
14109
14188
|
const DEFAULT_HOSTNAME = "127.0.0.1";
|
|
14110
14189
|
const DEFAULT_CALLBACK_PATH = "/oauth/callback";
|
|
14111
14190
|
const SUCCESS_HTML = page("OAuth complete", "OAuth complete. You can close this window.");
|
|
@@ -14279,6 +14358,28 @@ function createOAuthCallbackServer() {
|
|
|
14279
14358
|
function buildRedirectUrl(host, port, path) {
|
|
14280
14359
|
return `http://${formatHostForUrl(host)}:${port}${path}`;
|
|
14281
14360
|
}
|
|
14361
|
+
var OAuthCallbackError = class extends Error {
|
|
14362
|
+
name = "OAuthCallbackError";
|
|
14363
|
+
oauthError;
|
|
14364
|
+
oauthErrorDescription;
|
|
14365
|
+
source;
|
|
14366
|
+
constructor(params) {
|
|
14367
|
+
super(callbackErrorMessage(params));
|
|
14368
|
+
this.source = params.source;
|
|
14369
|
+
if (params.source === "redirect") {
|
|
14370
|
+
if (params.error) this.oauthError = params.error;
|
|
14371
|
+
if (params.error_description) this.oauthErrorDescription = params.error_description;
|
|
14372
|
+
}
|
|
14373
|
+
}
|
|
14374
|
+
};
|
|
14375
|
+
var OAuthCallbackTimeoutError = class extends Error {
|
|
14376
|
+
name = "OAuthCallbackTimeoutError";
|
|
14377
|
+
timeoutMs;
|
|
14378
|
+
constructor(timeoutMs) {
|
|
14379
|
+
super(`OAuth callback timed out after ${Math.round(timeoutMs / 1e3)}s`);
|
|
14380
|
+
this.timeoutMs = timeoutMs;
|
|
14381
|
+
}
|
|
14382
|
+
};
|
|
14282
14383
|
function toRunnerOAuthError(err) {
|
|
14283
14384
|
const failure = findIssuerBindingFailure(err);
|
|
14284
14385
|
if (failure) {
|
|
@@ -14343,7 +14444,7 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
14343
14444
|
}
|
|
14344
14445
|
},
|
|
14345
14446
|
onError: (params) => {
|
|
14346
|
-
flowReject(new
|
|
14447
|
+
flowReject(new OAuthCallbackError(params));
|
|
14347
14448
|
}
|
|
14348
14449
|
}));
|
|
14349
14450
|
options.onCallbackServer?.(server);
|
|
@@ -14354,7 +14455,7 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
14354
14455
|
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
14355
14456
|
}), new Promise((_, reject) => {
|
|
14356
14457
|
timeoutId = setTimeout(() => {
|
|
14357
|
-
reject(
|
|
14458
|
+
reject(new OAuthCallbackTimeoutError(timeoutMs));
|
|
14358
14459
|
}, timeoutMs);
|
|
14359
14460
|
})]);
|
|
14360
14461
|
waitForCallback.catch(() => {});
|
|
@@ -14385,13 +14486,11 @@ async function runRunnerInteractiveOAuth(options) {
|
|
|
14385
14486
|
await server.stop().catch(() => {});
|
|
14386
14487
|
}
|
|
14387
14488
|
}
|
|
14388
|
-
|
|
14389
|
-
//#region src/oauthMessageTone.ts
|
|
14489
|
+
// src/oauthMessageTone.ts
|
|
14390
14490
|
function oauthMessageToneFor(message, warningText) {
|
|
14391
14491
|
return message !== null && message === warningText ? "warning" : "info";
|
|
14392
14492
|
}
|
|
14393
|
-
|
|
14394
|
-
//#region src/logger.ts
|
|
14493
|
+
// src/logger.ts
|
|
14395
14494
|
let tuiLoggerInstance;
|
|
14396
14495
|
function getTuiLogger() {
|
|
14397
14496
|
if (!tuiLoggerInstance) {
|
|
@@ -14408,8 +14507,7 @@ function getTuiLogger() {
|
|
|
14408
14507
|
}
|
|
14409
14508
|
return tuiLoggerInstance;
|
|
14410
14509
|
}
|
|
14411
|
-
|
|
14412
|
-
//#region ../../core/node/openUrl.ts
|
|
14510
|
+
// ../../core/node/openUrl.ts
|
|
14413
14511
|
const OPEN_URL_TIMEOUT_MS = 5e3;
|
|
14414
14512
|
const OPENABLE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
14415
14513
|
function toOpenableHref(href) {
|
|
@@ -14437,8 +14535,7 @@ async function openUrl$1(url, timeoutMs = OPEN_URL_TIMEOUT_MS) {
|
|
|
14437
14535
|
clearTimeout(timer);
|
|
14438
14536
|
}
|
|
14439
14537
|
}
|
|
14440
|
-
|
|
14441
|
-
//#region src/utils/openUrl.ts
|
|
14538
|
+
// src/utils/openUrl.ts
|
|
14442
14539
|
function browserOpenFailedMessage(href) {
|
|
14443
14540
|
return `Could not open a browser automatically. Open this URL manually to authorize: ${href}`;
|
|
14444
14541
|
}
|
|
@@ -14450,13 +14547,11 @@ async function openUrl(url, onFailure) {
|
|
|
14450
14547
|
onFailure?.(browserOpenFailedMessage(href));
|
|
14451
14548
|
}
|
|
14452
14549
|
}
|
|
14453
|
-
|
|
14454
|
-
//#region src/utils/tuiOAuth.ts
|
|
14550
|
+
// src/utils/tuiOAuth.ts
|
|
14455
14551
|
function isStepUpConfirmation(challenge, settings) {
|
|
14456
14552
|
return isStepUpConfirmation$1(challenge, { enterpriseManaged: settings?.enterpriseManaged });
|
|
14457
14553
|
}
|
|
14458
|
-
|
|
14459
|
-
//#region src/components/tabsConfig.ts
|
|
14554
|
+
// src/components/tabsConfig.ts
|
|
14460
14555
|
const tabs = [
|
|
14461
14556
|
{
|
|
14462
14557
|
id: "info",
|
|
@@ -14542,8 +14637,7 @@ function tabBarRows(visible, counts, width) {
|
|
|
14542
14637
|
}
|
|
14543
14638
|
return rows;
|
|
14544
14639
|
}
|
|
14545
|
-
|
|
14546
|
-
//#region src/components/Tabs.tsx
|
|
14640
|
+
// src/components/Tabs.tsx
|
|
14547
14641
|
function splitLabelAtAccelerator(label, accelerator) {
|
|
14548
14642
|
const idx = label.toLowerCase().indexOf(accelerator.toLowerCase());
|
|
14549
14643
|
if (idx < 0) return {
|
|
@@ -14604,8 +14698,7 @@ function Tabs({ activeTab, width, counts = {}, focused = false, showAuth = true,
|
|
|
14604
14698
|
})
|
|
14605
14699
|
});
|
|
14606
14700
|
}
|
|
14607
|
-
|
|
14608
|
-
//#region node_modules/ink-scroll-view/dist/index.js
|
|
14701
|
+
// node_modules/ink-scroll-view/dist/index.js
|
|
14609
14702
|
var MeasurableItem = ({ children, onMeasure, index, width, measureKey }) => {
|
|
14610
14703
|
const ref = useRef(null);
|
|
14611
14704
|
useLayoutEffect(() => {
|
|
@@ -14887,8 +14980,7 @@ var ScrollView = forwardRef(({ onScroll, onViewportSizeChange, onContentHeightCh
|
|
|
14887
14980
|
...boxProps
|
|
14888
14981
|
});
|
|
14889
14982
|
});
|
|
14890
|
-
|
|
14891
|
-
//#region src/components/InfoTab.tsx
|
|
14983
|
+
// src/components/InfoTab.tsx
|
|
14892
14984
|
function InfoTab({ serverName, serverConfig, serverSettings = null, serverState, width, height, focused = false, roots = [], onEditRoots }) {
|
|
14893
14985
|
const headerPairs = serverSettings?.headers ?? [];
|
|
14894
14986
|
const headersBlock = headerPairs.length > 0 ? /* @__PURE__ */ jsx(Box, {
|
|
@@ -15127,8 +15219,7 @@ function InfoTab({ serverName, serverConfig, serverSettings = null, serverState,
|
|
|
15127
15219
|
})] }) : null]
|
|
15128
15220
|
});
|
|
15129
15221
|
}
|
|
15130
|
-
|
|
15131
|
-
//#region src/components/SelectableItem.tsx
|
|
15222
|
+
// src/components/SelectableItem.tsx
|
|
15132
15223
|
function SelectableItem({ isSelected, bold, children }) {
|
|
15133
15224
|
return /* @__PURE__ */ jsxs(Box, {
|
|
15134
15225
|
flexShrink: 0,
|
|
@@ -15145,8 +15236,7 @@ function SelectableItem({ isSelected, bold, children }) {
|
|
|
15145
15236
|
})]
|
|
15146
15237
|
});
|
|
15147
15238
|
}
|
|
15148
|
-
|
|
15149
|
-
//#region src/utils/clipboard.ts
|
|
15239
|
+
// src/utils/clipboard.ts
|
|
15150
15240
|
const OSC52_LARGE_PAYLOAD_BYTES = 1e5;
|
|
15151
15241
|
function toCopyText(value) {
|
|
15152
15242
|
if (typeof value === "string") return value;
|
|
@@ -15246,8 +15336,7 @@ function useCopyKeys(value, label) {
|
|
|
15246
15336
|
function copyStatusColor(tone) {
|
|
15247
15337
|
return tone === "success" ? "green" : tone === "warning" ? "yellow" : "red";
|
|
15248
15338
|
}
|
|
15249
|
-
|
|
15250
|
-
//#region src/utils/oauthDisplay.ts
|
|
15339
|
+
// src/utils/oauthDisplay.ts
|
|
15251
15340
|
function formatAuthProtocol(protocol) {
|
|
15252
15341
|
return protocol === "ema" ? "Enterprise-managed" : "Standard";
|
|
15253
15342
|
}
|
|
@@ -15269,8 +15358,7 @@ function formatScopes(state) {
|
|
|
15269
15358
|
const scopes = (state.grantedScope ?? state.configuredScope)?.split(" ").filter(Boolean);
|
|
15270
15359
|
return scopes && scopes.length > 0 ? scopes.join(", ") : void 0;
|
|
15271
15360
|
}
|
|
15272
|
-
|
|
15273
|
-
//#region src/utils/errorText.ts
|
|
15361
|
+
// src/utils/errorText.ts
|
|
15274
15362
|
function errorMessage$1(err) {
|
|
15275
15363
|
return redactUrlsInText(err instanceof Error ? err.message : String(err));
|
|
15276
15364
|
}
|
|
@@ -15280,8 +15368,128 @@ function redactErrorText(text) {
|
|
|
15280
15368
|
function redactedJson(value) {
|
|
15281
15369
|
return redactUrlsInText(JSON.stringify(value, null, 2) ?? String(value));
|
|
15282
15370
|
}
|
|
15283
|
-
|
|
15284
|
-
|
|
15371
|
+
// ../../core/auth/accessTokenClaims.ts
|
|
15372
|
+
const CONTROL_CHARS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
15373
|
+
function clean(value) {
|
|
15374
|
+
return value.replace(CONTROL_CHARS, "");
|
|
15375
|
+
}
|
|
15376
|
+
function stringClaim(value) {
|
|
15377
|
+
if (typeof value !== "string") return void 0;
|
|
15378
|
+
const cleaned = clean(value).trim();
|
|
15379
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
15380
|
+
}
|
|
15381
|
+
function listClaim(value) {
|
|
15382
|
+
const strings = (Array.isArray(value) ? value : [value]).map(stringClaim).filter((s) => s !== void 0);
|
|
15383
|
+
return strings.length > 0 ? strings : void 0;
|
|
15384
|
+
}
|
|
15385
|
+
function scopeString(value) {
|
|
15386
|
+
const s = stringClaim(value);
|
|
15387
|
+
if (s === void 0) return void 0;
|
|
15388
|
+
return s.split(/\s+/).filter(Boolean);
|
|
15389
|
+
}
|
|
15390
|
+
function numericClaim(value) {
|
|
15391
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
15392
|
+
}
|
|
15393
|
+
function summarizeAccessToken(tokens) {
|
|
15394
|
+
const claims = decodeJwtPayload(tokens.access_token)?.payload;
|
|
15395
|
+
if (claims && typeof claims === "object" && !Array.isArray(claims)) return {
|
|
15396
|
+
format: "jwt",
|
|
15397
|
+
issuer: stringClaim(claims.iss),
|
|
15398
|
+
audience: listClaim(claims.aud),
|
|
15399
|
+
subject: stringClaim(claims.sub),
|
|
15400
|
+
clientId: stringClaim(claims.client_id) ?? stringClaim(claims.azp),
|
|
15401
|
+
scopes: scopeString(claims.scope) ?? (typeof claims.scp === "string" ? scopeString(claims.scp) : listClaim(claims.scp)),
|
|
15402
|
+
issuedAt: numericClaim(claims.iat),
|
|
15403
|
+
expiresAt: numericClaim(claims.exp)
|
|
15404
|
+
};
|
|
15405
|
+
return {
|
|
15406
|
+
format: "opaque",
|
|
15407
|
+
scopes: scopeString(tokens.scope),
|
|
15408
|
+
expiresIn: numericClaim(tokens.expires_in)
|
|
15409
|
+
};
|
|
15410
|
+
}
|
|
15411
|
+
function isAccessTokenSummaryExpired(summary, nowMs) {
|
|
15412
|
+
return summary.expiresAt !== void 0 && summary.expiresAt * 1e3 <= nowMs;
|
|
15413
|
+
}
|
|
15414
|
+
function formatDuration(seconds) {
|
|
15415
|
+
const s = Math.floor(Math.abs(seconds));
|
|
15416
|
+
if (s < 60) return `${s}s`;
|
|
15417
|
+
const m = Math.floor(s / 60);
|
|
15418
|
+
if (m < 60) return `${m}m`;
|
|
15419
|
+
const h = Math.floor(m / 60);
|
|
15420
|
+
if (h < 24) return m % 60 === 0 ? `${h}h` : `${h}h ${m % 60}m`;
|
|
15421
|
+
const d = Math.floor(h / 24);
|
|
15422
|
+
return h % 24 === 0 ? `${d}d` : `${d}d ${h % 24}h`;
|
|
15423
|
+
}
|
|
15424
|
+
function formatEpoch(epochSeconds) {
|
|
15425
|
+
const date = /* @__PURE__ */ new Date(epochSeconds * 1e3);
|
|
15426
|
+
return Number.isNaN(date.getTime()) ? String(epochSeconds) : date.toISOString();
|
|
15427
|
+
}
|
|
15428
|
+
function relativeTo(epochSeconds, nowMs) {
|
|
15429
|
+
const delta = epochSeconds - nowMs / 1e3;
|
|
15430
|
+
return delta >= 0 ? `in ${formatDuration(delta)}` : `${formatDuration(delta)} ago`;
|
|
15431
|
+
}
|
|
15432
|
+
function accessTokenDetailLines(summary, nowMs) {
|
|
15433
|
+
const lines = [];
|
|
15434
|
+
if (summary.format === "jwt") {
|
|
15435
|
+
lines.push({
|
|
15436
|
+
label: "Format",
|
|
15437
|
+
value: "JWT (signature not verified)"
|
|
15438
|
+
});
|
|
15439
|
+
if (summary.issuer) lines.push({
|
|
15440
|
+
label: "Issuer",
|
|
15441
|
+
value: summary.issuer
|
|
15442
|
+
});
|
|
15443
|
+
if (summary.audience) lines.push({
|
|
15444
|
+
label: "Audience",
|
|
15445
|
+
value: summary.audience.join(", ")
|
|
15446
|
+
});
|
|
15447
|
+
if (summary.subject) lines.push({
|
|
15448
|
+
label: "Subject",
|
|
15449
|
+
value: summary.subject
|
|
15450
|
+
});
|
|
15451
|
+
if (summary.clientId) lines.push({
|
|
15452
|
+
label: "Client",
|
|
15453
|
+
value: summary.clientId
|
|
15454
|
+
});
|
|
15455
|
+
if (summary.scopes) lines.push({
|
|
15456
|
+
label: "Scopes",
|
|
15457
|
+
value: summary.scopes.join(", ")
|
|
15458
|
+
});
|
|
15459
|
+
if (summary.issuedAt !== void 0) lines.push({
|
|
15460
|
+
label: "Issued",
|
|
15461
|
+
value: `${formatEpoch(summary.issuedAt)} (${relativeTo(summary.issuedAt, nowMs)})`
|
|
15462
|
+
});
|
|
15463
|
+
if (summary.expiresAt !== void 0) {
|
|
15464
|
+
const expired = isAccessTokenSummaryExpired(summary, nowMs);
|
|
15465
|
+
const rel = relativeTo(summary.expiresAt, nowMs);
|
|
15466
|
+
lines.push({
|
|
15467
|
+
label: "Expires",
|
|
15468
|
+
value: `${formatEpoch(summary.expiresAt)} (${expired ? `expired ${rel}` : rel})`
|
|
15469
|
+
});
|
|
15470
|
+
} else lines.push({
|
|
15471
|
+
label: "Expires",
|
|
15472
|
+
value: "no exp claim"
|
|
15473
|
+
});
|
|
15474
|
+
return lines;
|
|
15475
|
+
}
|
|
15476
|
+
lines.push({
|
|
15477
|
+
label: "Format",
|
|
15478
|
+
value: "Opaque (not a JWT)"
|
|
15479
|
+
});
|
|
15480
|
+
if (summary.scopes) lines.push({
|
|
15481
|
+
label: "Scopes",
|
|
15482
|
+
value: summary.scopes.join(", ")
|
|
15483
|
+
});
|
|
15484
|
+
lines.push({
|
|
15485
|
+
label: "Expires in",
|
|
15486
|
+
value: summary.expiresIn !== void 0 ? `${formatDuration(summary.expiresIn)} from issuance (token response expires_in)` : "not stated by the token response"
|
|
15487
|
+
});
|
|
15488
|
+
return lines;
|
|
15489
|
+
}
|
|
15490
|
+
// src/components/AuthTab.tsx
|
|
15491
|
+
const NO_REFUSALS = [];
|
|
15492
|
+
const readFetchRefusals = (client) => client.getFetchRefusals();
|
|
15285
15493
|
function OAuthDetailRow({ label, value }) {
|
|
15286
15494
|
return /* @__PURE__ */ jsxs(Box, {
|
|
15287
15495
|
flexDirection: "row",
|
|
@@ -15367,6 +15575,7 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
15367
15575
|
inspectorClient.removeEventListener("oauthComplete", update);
|
|
15368
15576
|
};
|
|
15369
15577
|
}, [inspectorClient, refreshOAuthState]);
|
|
15578
|
+
const fetchRefusals = useStoreSnapshot(inspectorClient, "fetchRefused", readFetchRefusals, NO_REFUSALS);
|
|
15370
15579
|
const accessToken = oauthState?.tokens?.access_token;
|
|
15371
15580
|
const { handleCopyKey, status: copyStatus } = useCopyKeys(accessToken, "access token");
|
|
15372
15581
|
useInput((input, key) => {
|
|
@@ -15438,6 +15647,7 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
15438
15647
|
})
|
|
15439
15648
|
});
|
|
15440
15649
|
const scopes = oauthState ? formatScopes(oauthState) : void 0;
|
|
15650
|
+
const tokenDetails = oauthState?.tokens?.access_token ? accessTokenDetailLines(summarizeAccessToken(oauthState.tokens), Date.now()) : [];
|
|
15441
15651
|
return /* @__PURE__ */ jsxs(Box, {
|
|
15442
15652
|
width,
|
|
15443
15653
|
height,
|
|
@@ -15476,6 +15686,19 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
15476
15686
|
color: oauthMessageTone === "warning" ? "yellow" : "cyan",
|
|
15477
15687
|
children: oauthMessage
|
|
15478
15688
|
}),
|
|
15689
|
+
fetchRefusals.length > 0 && /* @__PURE__ */ jsxs(Box, {
|
|
15690
|
+
marginTop: 1,
|
|
15691
|
+
flexDirection: "column",
|
|
15692
|
+
gap: 0,
|
|
15693
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
15694
|
+
bold: true,
|
|
15695
|
+
color: "yellow",
|
|
15696
|
+
children: "Refused requests"
|
|
15697
|
+
}), fetchRefusals.map((refusal) => /* @__PURE__ */ jsx(Text, {
|
|
15698
|
+
color: "yellow",
|
|
15699
|
+
children: formatFetchRefusal(refusal)
|
|
15700
|
+
}, `${refusal.url} ${refusal.reason}`))]
|
|
15701
|
+
}),
|
|
15479
15702
|
pendingStepUp ? /* @__PURE__ */ jsxs(Box, {
|
|
15480
15703
|
marginTop: 1,
|
|
15481
15704
|
flexDirection: "column",
|
|
@@ -15537,53 +15760,68 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
15537
15760
|
flexDirection: "column",
|
|
15538
15761
|
marginTop: 1,
|
|
15539
15762
|
gap: 0,
|
|
15540
|
-
children: [
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
|
|
15556
|
-
|
|
15557
|
-
|
|
15558
|
-
|
|
15559
|
-
|
|
15560
|
-
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
|
|
15564
|
-
|
|
15565
|
-
|
|
15566
|
-
|
|
15567
|
-
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
15574
|
-
|
|
15575
|
-
|
|
15576
|
-
|
|
15577
|
-
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
|
|
15582
|
-
|
|
15583
|
-
|
|
15584
|
-
|
|
15585
|
-
|
|
15586
|
-
|
|
15763
|
+
children: [
|
|
15764
|
+
/* @__PURE__ */ jsx(Text, {
|
|
15765
|
+
bold: true,
|
|
15766
|
+
children: "OAuth Details"
|
|
15767
|
+
}),
|
|
15768
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
15769
|
+
marginTop: 1,
|
|
15770
|
+
flexDirection: "column",
|
|
15771
|
+
paddingLeft: 0,
|
|
15772
|
+
gap: 0,
|
|
15773
|
+
children: [
|
|
15774
|
+
/* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15775
|
+
label: "Protocol",
|
|
15776
|
+
value: formatAuthProtocol(oauthState.protocol)
|
|
15777
|
+
}),
|
|
15778
|
+
/* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15779
|
+
label: "Status",
|
|
15780
|
+
value: oauthState.authorized ? "Authorized" : "Not authorized"
|
|
15781
|
+
}),
|
|
15782
|
+
oauthState.client?.clientId && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15783
|
+
label: "Client ID",
|
|
15784
|
+
value: oauthState.client.clientId
|
|
15785
|
+
}),
|
|
15786
|
+
oauthState.client?.registrationKind && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15787
|
+
label: "Client registration",
|
|
15788
|
+
value: formatClientRegistrationKind(oauthState.client.registrationKind)
|
|
15789
|
+
}),
|
|
15790
|
+
oauthState.protocol === "ema" && oauthState.ema?.idpSession && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15791
|
+
label: "IdP session",
|
|
15792
|
+
value: formatIdpSession(oauthState.ema.idpSession)
|
|
15793
|
+
}),
|
|
15794
|
+
oauthState.authorizationServerMetadata?.authorization_endpoint && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15795
|
+
label: "Auth URL",
|
|
15796
|
+
value: oauthState.authorizationServerMetadata.authorization_endpoint
|
|
15797
|
+
}),
|
|
15798
|
+
scopes && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15799
|
+
label: "Scopes",
|
|
15800
|
+
value: scopes
|
|
15801
|
+
}),
|
|
15802
|
+
accessToken && /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15803
|
+
label: "Access token",
|
|
15804
|
+
value: `${accessToken.slice(0, 24)}…`
|
|
15805
|
+
}),
|
|
15806
|
+
accessToken && copyStatus && /* @__PURE__ */ jsx(Text, {
|
|
15807
|
+
color: copyStatusColor(copyStatus.tone),
|
|
15808
|
+
children: copyStatus.message
|
|
15809
|
+
})
|
|
15810
|
+
]
|
|
15811
|
+
}),
|
|
15812
|
+
tokenDetails.length > 0 && /* @__PURE__ */ jsxs(Box, {
|
|
15813
|
+
marginTop: 1,
|
|
15814
|
+
flexDirection: "column",
|
|
15815
|
+
gap: 0,
|
|
15816
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
15817
|
+
bold: true,
|
|
15818
|
+
children: "Access Token Details"
|
|
15819
|
+
}), tokenDetails.map((line) => /* @__PURE__ */ jsx(OAuthDetailRow, {
|
|
15820
|
+
label: line.label,
|
|
15821
|
+
value: line.value
|
|
15822
|
+
}, line.label))]
|
|
15823
|
+
})
|
|
15824
|
+
]
|
|
15587
15825
|
}) : oauthStatus !== "authenticating" && /* @__PURE__ */ jsxs(Box, {
|
|
15588
15826
|
marginTop: 1,
|
|
15589
15827
|
flexDirection: "column",
|
|
@@ -15645,8 +15883,7 @@ function AuthTab({ serverName, inspectorClient, oauthStatus, oauthMessage, oauth
|
|
|
15645
15883
|
]
|
|
15646
15884
|
});
|
|
15647
15885
|
}
|
|
15648
|
-
|
|
15649
|
-
//#region src/hooks/useSelectableList.ts
|
|
15886
|
+
// src/hooks/useSelectableList.ts
|
|
15650
15887
|
function clampFirstVisible(first, selected, visibleCount) {
|
|
15651
15888
|
if (selected < first) return selected;
|
|
15652
15889
|
if (selected >= first + visibleCount) return selected - visibleCount + 1;
|
|
@@ -15682,8 +15919,7 @@ function useSelectableList(itemCount, visibleCount, options) {
|
|
|
15682
15919
|
setSelection
|
|
15683
15920
|
};
|
|
15684
15921
|
}
|
|
15685
|
-
|
|
15686
|
-
//#region src/hooks/useListFilter.ts
|
|
15922
|
+
// src/hooks/useListFilter.ts
|
|
15687
15923
|
function printable(input) {
|
|
15688
15924
|
return input.replace(/[\u0000-\u001f\u007f]/g, "");
|
|
15689
15925
|
}
|
|
@@ -15810,8 +16046,7 @@ function ListFilterBar({ query, editing, focused }) {
|
|
|
15810
16046
|
function filterCount(active, shown, total) {
|
|
15811
16047
|
return active ? `${shown}/${total}` : String(total);
|
|
15812
16048
|
}
|
|
15813
|
-
|
|
15814
|
-
//#region src/components/ResourcesTab.tsx
|
|
16049
|
+
// src/components/ResourcesTab.tsx
|
|
15815
16050
|
function resourceFilterFields(item) {
|
|
15816
16051
|
return item.type === "resource" ? [
|
|
15817
16052
|
item.data.name,
|
|
@@ -16151,8 +16386,7 @@ function ResourcesTab({ resources, resourceTemplates = [], inspectorClient, widt
|
|
|
16151
16386
|
})]
|
|
16152
16387
|
});
|
|
16153
16388
|
}
|
|
16154
|
-
|
|
16155
|
-
//#region src/components/PromptsTab.tsx
|
|
16389
|
+
// src/components/PromptsTab.tsx
|
|
16156
16390
|
function promptFilterFields(prompt) {
|
|
16157
16391
|
return [prompt.name, prompt.title];
|
|
16158
16392
|
}
|
|
@@ -16368,8 +16602,7 @@ function PromptsTab({ prompts, inspectorClient, width, height, focusedPane = nul
|
|
|
16368
16602
|
})]
|
|
16369
16603
|
});
|
|
16370
16604
|
}
|
|
16371
|
-
|
|
16372
|
-
//#region ../../core/extension/skills/verification.ts
|
|
16605
|
+
// ../../core/extension/skills/verification.ts
|
|
16373
16606
|
const DEFAULT_SKILL_BUDGET_HINT = {
|
|
16374
16607
|
raise: "with the server's skillCatalogMaxSkills / skillCatalogMaxBytes settings",
|
|
16375
16608
|
verifyOne: "by verifying this skill alone"
|
|
@@ -16542,8 +16775,7 @@ async function verifySkills(client, entries, metadata, budgetHint = DEFAULT_SKIL
|
|
|
16542
16775
|
}
|
|
16543
16776
|
return reports;
|
|
16544
16777
|
}
|
|
16545
|
-
|
|
16546
|
-
//#region src/components/SkillsTab.tsx
|
|
16778
|
+
// src/components/SkillsTab.tsx
|
|
16547
16779
|
function skillFilterFields(skill) {
|
|
16548
16780
|
return [skillDisplayName(skill), skill.frontmatter.name];
|
|
16549
16781
|
}
|
|
@@ -16998,8 +17230,7 @@ function SkillsTab({ skills, pageCount, loadError = null, inspectorClient, width
|
|
|
16998
17230
|
})]
|
|
16999
17231
|
});
|
|
17000
17232
|
}
|
|
17001
|
-
|
|
17002
|
-
//#region ../../core/json/schemaLint.ts
|
|
17233
|
+
// ../../core/json/schemaLint.ts
|
|
17003
17234
|
const BOOLEAN_VALUED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
17004
17235
|
"additionalProperties",
|
|
17005
17236
|
"unevaluatedProperties",
|
|
@@ -17193,8 +17424,7 @@ function lintToolSchemas(tool) {
|
|
|
17193
17424
|
if (tool.outputSchema !== void 0) lintSchema(tool.outputSchema, "outputSchema", findings);
|
|
17194
17425
|
return findings;
|
|
17195
17426
|
}
|
|
17196
|
-
|
|
17197
|
-
//#region src/components/ToolsTab.tsx
|
|
17427
|
+
// src/components/ToolsTab.tsx
|
|
17198
17428
|
const SEVERITY_MARKER = {
|
|
17199
17429
|
error: {
|
|
17200
17430
|
glyph: "!",
|
|
@@ -17458,8 +17688,7 @@ function ToolsTab({ tools, isConnected, width, height, focusedPane = null, onTes
|
|
|
17458
17688
|
})]
|
|
17459
17689
|
});
|
|
17460
17690
|
}
|
|
17461
|
-
|
|
17462
|
-
//#region src/components/NotificationsTab.tsx
|
|
17691
|
+
// src/components/NotificationsTab.tsx
|
|
17463
17692
|
function NotificationsTab({ stderrLogs, width, height, onCountChange, focused = false }) {
|
|
17464
17693
|
const scrollViewRef = useRef(null);
|
|
17465
17694
|
const onCountChangeRef = useRef(onCountChange);
|
|
@@ -17547,8 +17776,7 @@ function layoutBody(body, maxLines = 500, maxLineChars = MAX_BODY_LINE_CHARS) {
|
|
|
17547
17776
|
totalLines: all.length
|
|
17548
17777
|
};
|
|
17549
17778
|
}
|
|
17550
|
-
|
|
17551
|
-
//#region src/components/BodyLines.tsx
|
|
17779
|
+
// src/components/BodyLines.tsx
|
|
17552
17780
|
function BodyLines({ body, keyPrefix }) {
|
|
17553
17781
|
const { lines, hiddenLines, totalLines } = layoutBody(body);
|
|
17554
17782
|
return /* @__PURE__ */ jsxs(Fragment, { children: [lines.map((line, idx) => /* @__PURE__ */ jsx(Box, {
|
|
@@ -17575,8 +17803,7 @@ function BodyLines({ body, keyPrefix }) {
|
|
|
17575
17803
|
})
|
|
17576
17804
|
})] });
|
|
17577
17805
|
}
|
|
17578
|
-
|
|
17579
|
-
//#region src/components/HistoryTab.tsx
|
|
17806
|
+
// src/components/HistoryTab.tsx
|
|
17580
17807
|
function HistoryTab({ messages, width, height, onCountChange, focusedPane = null, onViewDetails, modalOpen = false }) {
|
|
17581
17808
|
const visibleCount = Math.max(1, height - 7);
|
|
17582
17809
|
const { selectedIndex, firstVisible, setSelection } = useSelectableList(messages.length, visibleCount);
|
|
@@ -17784,8 +18011,7 @@ function HistoryTab({ messages, width, height, onCountChange, focusedPane = null
|
|
|
17784
18011
|
})]
|
|
17785
18012
|
});
|
|
17786
18013
|
}
|
|
17787
|
-
|
|
17788
|
-
//#region src/components/RequestsTab.tsx
|
|
18014
|
+
// src/components/RequestsTab.tsx
|
|
17789
18015
|
function RequestsTab({ requests, width, height, onCountChange, focusedPane = null, onViewDetails, modalOpen = false }) {
|
|
17790
18016
|
const visibleCount = Math.max(1, height - 7);
|
|
17791
18017
|
const { selectedIndex, firstVisible, setSelection } = useSelectableList(requests.length, visibleCount);
|
|
@@ -18081,8 +18307,7 @@ function RequestsTab({ requests, width, height, onCountChange, focusedPane = nul
|
|
|
18081
18307
|
})]
|
|
18082
18308
|
});
|
|
18083
18309
|
}
|
|
18084
|
-
|
|
18085
|
-
//#region node_modules/ink-form/lib/FormHeader.js
|
|
18310
|
+
// node_modules/ink-form/lib/FormHeader.js
|
|
18086
18311
|
const FormHeader = (props) => {
|
|
18087
18312
|
const sections = props.form.sections;
|
|
18088
18313
|
useInput((input, key) => {
|
|
@@ -18101,8 +18326,7 @@ const FormHeader = (props) => {
|
|
|
18101
18326
|
underline: props.currentTab === id
|
|
18102
18327
|
}, section.title), React$1.createElement(Text, null, " "))) : React$1.createElement(Box, null, React$1.createElement(Text, null, "Editing ", props.editingField)))));
|
|
18103
18328
|
};
|
|
18104
|
-
|
|
18105
|
-
//#region node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
18329
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
18106
18330
|
const ANSI_BACKGROUND_OFFSET = 10;
|
|
18107
18331
|
const wrapAnsi16 = (offset = 0) => (code) => `\u001B[${code + offset}m`;
|
|
18108
18332
|
const wrapAnsi256 = (offset = 0) => (code) => `\u001B[${38 + offset};5;${code}m`;
|
|
@@ -18265,8 +18489,7 @@ function assembleStyles() {
|
|
|
18265
18489
|
return styles$1;
|
|
18266
18490
|
}
|
|
18267
18491
|
const ansiStyles = assembleStyles();
|
|
18268
|
-
|
|
18269
|
-
//#region node_modules/chalk/source/vendor/supports-color/index.js
|
|
18492
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
18270
18493
|
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
|
|
18271
18494
|
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
18272
18495
|
const position = argv.indexOf(prefix + flag);
|
|
@@ -18353,8 +18576,7 @@ const supportsColor = {
|
|
|
18353
18576
|
stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
|
|
18354
18577
|
stderr: createSupportsColor({ isTTY: tty.isatty(2) })
|
|
18355
18578
|
};
|
|
18356
|
-
|
|
18357
|
-
//#region node_modules/chalk/source/utilities.js
|
|
18579
|
+
// node_modules/chalk/source/utilities.js
|
|
18358
18580
|
function stringReplaceAll(string, substring, replacer) {
|
|
18359
18581
|
let index = string.indexOf(substring);
|
|
18360
18582
|
if (index === -1) return string;
|
|
@@ -18381,8 +18603,7 @@ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
|
18381
18603
|
returnValue += string.slice(endIndex);
|
|
18382
18604
|
return returnValue;
|
|
18383
18605
|
}
|
|
18384
|
-
|
|
18385
|
-
//#region node_modules/chalk/source/index.js
|
|
18606
|
+
// node_modules/chalk/source/index.js
|
|
18386
18607
|
const { stdout: stdoutColor, stderr: stderrColor } = supportsColor;
|
|
18387
18608
|
const GENERATOR = Symbol("GENERATOR");
|
|
18388
18609
|
const STYLER = Symbol("STYLER");
|
|
@@ -18503,8 +18724,7 @@ const applyStyle = (self, string) => {
|
|
|
18503
18724
|
Object.defineProperties(createChalk.prototype, styles);
|
|
18504
18725
|
const chalk = createChalk();
|
|
18505
18726
|
createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
18506
|
-
|
|
18507
|
-
//#region node_modules/ink-text-input/build/index.js
|
|
18727
|
+
// node_modules/ink-text-input/build/index.js
|
|
18508
18728
|
function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit }) {
|
|
18509
18729
|
const [state, setState] = useState({
|
|
18510
18730
|
cursorOffset: (originalValue || "").length,
|
|
@@ -18573,8 +18793,7 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
|
|
|
18573
18793
|
}, { isActive: focus });
|
|
18574
18794
|
return React.createElement(Text, null, placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue);
|
|
18575
18795
|
}
|
|
18576
|
-
|
|
18577
|
-
//#region node_modules/ink-form/lib/NumberFieldRenderer.js
|
|
18796
|
+
// node_modules/ink-form/lib/NumberFieldRenderer.js
|
|
18578
18797
|
const FLOAT_REGEX = /^-?((\d+)|(\d*\.\d+))$/;
|
|
18579
18798
|
const INTEGER_REGEX = /^-?\d+$/;
|
|
18580
18799
|
const NumberFieldRenderer = (props) => {
|
|
@@ -18623,8 +18842,7 @@ const NumberFieldRenderer = (props) => {
|
|
|
18623
18842
|
onSubmit: () => props.onSetEditingField(void 0)
|
|
18624
18843
|
})), React.createElement(Box, null, React.createElement(Text, { dimColor: true }, "Press UP/DOWN to increase or decrease the value.")));
|
|
18625
18844
|
};
|
|
18626
|
-
|
|
18627
|
-
//#region node_modules/ink-form/lib/managers/FloatFormFieldManager.js
|
|
18845
|
+
// node_modules/ink-form/lib/managers/FloatFormFieldManager.js
|
|
18628
18846
|
var FloatFormFieldManager = class {
|
|
18629
18847
|
type = "float";
|
|
18630
18848
|
renderField = (props) => React.createElement(NumberFieldRenderer, {
|
|
@@ -18633,8 +18851,7 @@ var FloatFormFieldManager = class {
|
|
|
18633
18851
|
});
|
|
18634
18852
|
renderValue = (props) => React.createElement(React.Fragment, null, props.value);
|
|
18635
18853
|
};
|
|
18636
|
-
|
|
18637
|
-
//#region node_modules/ink-form/lib/managers/IntegerFormFieldManager.js
|
|
18854
|
+
// node_modules/ink-form/lib/managers/IntegerFormFieldManager.js
|
|
18638
18855
|
var IntegerFormFieldManager = class {
|
|
18639
18856
|
type = "integer";
|
|
18640
18857
|
renderField = (props) => React.createElement(NumberFieldRenderer, {
|
|
@@ -18643,16 +18860,14 @@ var IntegerFormFieldManager = class {
|
|
|
18643
18860
|
});
|
|
18644
18861
|
renderValue = (props) => React.createElement(React.Fragment, null, props.value);
|
|
18645
18862
|
};
|
|
18646
|
-
|
|
18647
|
-
//#region node_modules/is-unicode-supported/index.js
|
|
18863
|
+
// node_modules/is-unicode-supported/index.js
|
|
18648
18864
|
function isUnicodeSupported() {
|
|
18649
18865
|
const { env } = process$1;
|
|
18650
18866
|
const { TERM, TERM_PROGRAM } = env;
|
|
18651
18867
|
if (process$1.platform !== "win32") return TERM !== "linux";
|
|
18652
18868
|
return Boolean(env.WT_SESSION) || Boolean(env.TERMINUS_SUBLIME) || env.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
18653
18869
|
}
|
|
18654
|
-
|
|
18655
|
-
//#region node_modules/figures/index.js
|
|
18870
|
+
// node_modules/figures/index.js
|
|
18656
18871
|
const common = {
|
|
18657
18872
|
circleQuestionMark: "(?)",
|
|
18658
18873
|
questionMarkPrefix: "(?)",
|
|
@@ -18931,18 +19146,15 @@ const fallbackSymbols = {
|
|
|
18931
19146
|
};
|
|
18932
19147
|
const figures = isUnicodeSupported() ? mainSymbols : fallbackSymbols;
|
|
18933
19148
|
Object.entries(specialMainSymbols);
|
|
18934
|
-
|
|
18935
|
-
//#region node_modules/ink-select-input/build/Indicator.js
|
|
19149
|
+
// node_modules/ink-select-input/build/Indicator.js
|
|
18936
19150
|
function Indicator({ isSelected = false }) {
|
|
18937
19151
|
return React.createElement(Box, { marginRight: 1 }, isSelected ? React.createElement(Text, { color: "blue" }, figures.pointer) : React.createElement(Text, null, " "));
|
|
18938
19152
|
}
|
|
18939
|
-
|
|
18940
|
-
//#region node_modules/ink-select-input/build/Item.js
|
|
19153
|
+
// node_modules/ink-select-input/build/Item.js
|
|
18941
19154
|
function Item({ isSelected = false, label }) {
|
|
18942
19155
|
return React$1.createElement(Text, { color: isSelected ? "blue" : void 0 }, label);
|
|
18943
19156
|
}
|
|
18944
|
-
|
|
18945
|
-
//#region node_modules/to-rotated/index.js
|
|
19157
|
+
// node_modules/to-rotated/index.js
|
|
18946
19158
|
function toRotated(array, steps) {
|
|
18947
19159
|
if (!Array.isArray(array)) throw new TypeError(`Expected an array, got \`${typeof array}\`.`);
|
|
18948
19160
|
if (!Number.isSafeInteger(steps)) throw new TypeError(`The \`steps\` parameter must be an integer, got ${steps}.`);
|
|
@@ -18952,8 +19164,7 @@ function toRotated(array, steps) {
|
|
|
18952
19164
|
if (normalizedSteps === 0) return [...array];
|
|
18953
19165
|
return [...array.slice(-normalizedSteps), ...array.slice(0, -normalizedSteps)];
|
|
18954
19166
|
}
|
|
18955
|
-
|
|
18956
|
-
//#region node_modules/ink-select-input/build/SelectInput.js
|
|
19167
|
+
// node_modules/ink-select-input/build/SelectInput.js
|
|
18957
19168
|
function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicatorComponent = Indicator, itemComponent = Item, limit: customLimit, onSelect, onHighlight }) {
|
|
18958
19169
|
const hasLimit = typeof customLimit === "number" && items.length > customLimit;
|
|
18959
19170
|
const limit = hasLimit ? Math.min(customLimit, items.length) : items.length;
|
|
@@ -19020,8 +19231,7 @@ function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicator
|
|
|
19020
19231
|
}));
|
|
19021
19232
|
}));
|
|
19022
19233
|
}
|
|
19023
|
-
|
|
19024
|
-
//#region node_modules/ink-form/lib/managers/SelectFormFieldManager.js
|
|
19234
|
+
// node_modules/ink-form/lib/managers/SelectFormFieldManager.js
|
|
19025
19235
|
var SelectFormFieldManager = class {
|
|
19026
19236
|
type = "select";
|
|
19027
19237
|
renderField = (props) => React.createElement(Box, {
|
|
@@ -19037,8 +19247,7 @@ var SelectFormFieldManager = class {
|
|
|
19037
19247
|
}));
|
|
19038
19248
|
renderValue = (props) => React.createElement(React.Fragment, null, props.field.options.find((option) => option.value === props.value)?.label ?? props.value ?? "No value");
|
|
19039
19249
|
};
|
|
19040
|
-
|
|
19041
|
-
//#region node_modules/ink-form/lib/managers/StringFormFieldManager.js
|
|
19250
|
+
// node_modules/ink-form/lib/managers/StringFormFieldManager.js
|
|
19042
19251
|
var StringFormFieldManager = class {
|
|
19043
19252
|
type = "string";
|
|
19044
19253
|
renderField = (props) => React.createElement(Box, {
|
|
@@ -19057,8 +19266,7 @@ var StringFormFieldManager = class {
|
|
|
19057
19266
|
}));
|
|
19058
19267
|
renderValue = (props) => React.createElement(Transform, { transform: props.value !== void 0 && props.field.mask ? (text) => text.split("").map((char) => "*").join("") : (text) => text }, props.value);
|
|
19059
19268
|
};
|
|
19060
|
-
|
|
19061
|
-
//#region node_modules/ink-form/lib/managers/BooleanFormFieldManager.js
|
|
19269
|
+
// node_modules/ink-form/lib/managers/BooleanFormFieldManager.js
|
|
19062
19270
|
var BooleanFormFieldManager = class {
|
|
19063
19271
|
type = "boolean";
|
|
19064
19272
|
renderField = (props) => {
|
|
@@ -19074,8 +19282,7 @@ var BooleanFormFieldManager = class {
|
|
|
19074
19282
|
};
|
|
19075
19283
|
renderValue = (props) => React.createElement(Text, null, props.value === void 0 ? "[Not set]" : props.value ? "[True]" : "[False]");
|
|
19076
19284
|
};
|
|
19077
|
-
|
|
19078
|
-
//#region node_modules/ink-form/lib/managers/managers.js
|
|
19285
|
+
// node_modules/ink-form/lib/managers/managers.js
|
|
19079
19286
|
const managers = [
|
|
19080
19287
|
new FloatFormFieldManager(),
|
|
19081
19288
|
new IntegerFormFieldManager(),
|
|
@@ -19086,8 +19293,7 @@ const managers = [
|
|
|
19086
19293
|
const getManager = (formFieldType, customManagers = []) => {
|
|
19087
19294
|
return [...managers, ...customManagers].find((manager) => manager.type === formFieldType);
|
|
19088
19295
|
};
|
|
19089
|
-
|
|
19090
|
-
//#region node_modules/ink-form/lib/DescriptionRenderer.js
|
|
19296
|
+
// node_modules/ink-form/lib/DescriptionRenderer.js
|
|
19091
19297
|
const DescriptionRenderer = (props) => {
|
|
19092
19298
|
if (!props.description) return null;
|
|
19093
19299
|
else if (props.description.type) return props.description;
|
|
@@ -19098,8 +19304,7 @@ const DescriptionRenderer = (props) => {
|
|
|
19098
19304
|
}, React.createElement(Text, null, line))));
|
|
19099
19305
|
else return React.createElement(Text, null, props.description);
|
|
19100
19306
|
};
|
|
19101
|
-
|
|
19102
|
-
//#region node_modules/ink-form/lib/FormFieldRenderer.js
|
|
19307
|
+
// node_modules/ink-form/lib/FormFieldRenderer.js
|
|
19103
19308
|
const FormFieldRenderer = (props) => {
|
|
19104
19309
|
const manager = getManager(props.field.type, props.customManagers);
|
|
19105
19310
|
const [error, setError] = useState();
|
|
@@ -19165,13 +19370,11 @@ const FormFieldRenderer = (props) => {
|
|
|
19165
19370
|
}, React.createElement(Box, null, React.createElement(Text, null, props.field.label ?? props.field.name), props.field.required && React.createElement(Text, { color: "red" }, "*"), React.createElement(Text, null, ": ")), React.createElement(Box, null, component), props.field.description && React.createElement(Box, null, React.createElement(Text, { dimColor: true }, React.createElement(DescriptionRenderer, { description: props.field.description }))), error && React.createElement(Box, null, React.createElement(Text, { color: "red" }, "Error: ", error)), React.createElement(Box, { marginTop: 2 }, React.createElement(Text, { dimColor: true }, error ? React.createElement(React.Fragment, null, "Press ESC to cancel.") : React.createElement(React.Fragment, null, "Press ", manager?.needCtrlToReturnSave ? "CTRL+Enter" : "Enter", " to complete field, or ESC to cancel."))));
|
|
19166
19371
|
}
|
|
19167
19372
|
};
|
|
19168
|
-
|
|
19169
|
-
//#region node_modules/ink-form/lib/canSubmit.js
|
|
19373
|
+
// node_modules/ink-form/lib/canSubmit.js
|
|
19170
19374
|
const canSubmit = (form, value) => {
|
|
19171
19375
|
return form.sections.map((section) => section.fields).reduce((fields1, fields2) => [...fields1, ...fields2], []).map((field) => !field.required || value[field.name] !== void 0 && value[field.name] !== "").reduce((field1, field2) => field1 && field2, true);
|
|
19172
19376
|
};
|
|
19173
|
-
|
|
19174
|
-
//#region node_modules/ink-form/lib/SubmitButton.js
|
|
19377
|
+
// node_modules/ink-form/lib/SubmitButton.js
|
|
19175
19378
|
const SubmitButton = (props) => {
|
|
19176
19379
|
const { isFocused } = useFocus({ isActive: props.canSubmit });
|
|
19177
19380
|
useInput((input, key) => {
|
|
@@ -19190,8 +19393,7 @@ const SubmitButton = (props) => {
|
|
|
19190
19393
|
underline: isFocused
|
|
19191
19394
|
}, props.canSubmit ? "Submit form" : "Cannot submit form yet")));
|
|
19192
19395
|
};
|
|
19193
|
-
|
|
19194
|
-
//#region node_modules/ink-form/lib/Form.js
|
|
19396
|
+
// node_modules/ink-form/lib/Form.js
|
|
19195
19397
|
const Form = (props) => {
|
|
19196
19398
|
const isControlled = props.value !== void 0;
|
|
19197
19399
|
const [currentTab, setCurrentTab] = useState(0);
|
|
@@ -19251,8 +19453,29 @@ const Form = (props) => {
|
|
|
19251
19453
|
onSubmit: () => props.onSubmit?.(value)
|
|
19252
19454
|
})));
|
|
19253
19455
|
};
|
|
19254
|
-
|
|
19255
|
-
|
|
19456
|
+
// src/utils/multiSelectField.ts
|
|
19457
|
+
const MULTISELECT_FIELD_TYPE = "multiselect";
|
|
19458
|
+
function toggleChoice(selected, value, options) {
|
|
19459
|
+
const next = new Set(selected);
|
|
19460
|
+
if (next.has(value)) next.delete(value);
|
|
19461
|
+
else next.add(value);
|
|
19462
|
+
return options.map((option) => option.value).filter((each) => next.has(each));
|
|
19463
|
+
}
|
|
19464
|
+
function boundsHint(minItems, maxItems) {
|
|
19465
|
+
if (minItems !== void 0 && maxItems !== void 0) return minItems === maxItems ? `Choose exactly ${minItems}` : `Choose ${minItems} to ${maxItems}`;
|
|
19466
|
+
if (minItems !== void 0) return `Choose at least ${minItems}`;
|
|
19467
|
+
if (maxItems !== void 0) return `Choose at most ${maxItems}`;
|
|
19468
|
+
}
|
|
19469
|
+
function selectionLabel(options, value) {
|
|
19470
|
+
if (value === void 0) return "No value";
|
|
19471
|
+
if (value.length === 0) return "None selected";
|
|
19472
|
+
return value.map((each) => options.find((option) => option.value === each)?.label ?? each).join(", ");
|
|
19473
|
+
}
|
|
19474
|
+
function windowStart(cursor, count, limit) {
|
|
19475
|
+
if (count <= limit) return 0;
|
|
19476
|
+
return Math.min(Math.max(0, cursor - Math.floor(limit / 2)), count - limit);
|
|
19477
|
+
}
|
|
19478
|
+
// src/utils/schemaToForm.ts
|
|
19256
19479
|
function toSelectOptions(values, names) {
|
|
19257
19480
|
const useNames = names !== void 0 && names.length === values.length;
|
|
19258
19481
|
return values.map((val, index) => ({
|
|
@@ -19260,6 +19483,19 @@ function toSelectOptions(values, names) {
|
|
|
19260
19483
|
value: String(val)
|
|
19261
19484
|
}));
|
|
19262
19485
|
}
|
|
19486
|
+
function choiceOptions(members, names) {
|
|
19487
|
+
return toSelectOptions(members, names).map((option, index) => ({
|
|
19488
|
+
label: option.label,
|
|
19489
|
+
value: String(index)
|
|
19490
|
+
}));
|
|
19491
|
+
}
|
|
19492
|
+
function choiceIds(members, chosen) {
|
|
19493
|
+
return chosen.map((value) => members.findIndex((member) => sameJsonValue(member, value))).filter((index) => index >= 0).map(String);
|
|
19494
|
+
}
|
|
19495
|
+
function memberForChoiceId(members, id) {
|
|
19496
|
+
const index = typeof id === "string" && /^\d+$/.test(id) ? Number(id) : -1;
|
|
19497
|
+
return index >= 0 && index < members.length ? members[index] : id;
|
|
19498
|
+
}
|
|
19263
19499
|
function generatedNames(base, branches) {
|
|
19264
19500
|
const declared = [...Object.keys(base.properties ?? {}), ...branches.flatMap((branch) => branch.declaredFields)];
|
|
19265
19501
|
let variant = "__variant";
|
|
@@ -19296,6 +19532,12 @@ function constOf(schema) {
|
|
|
19296
19532
|
if (typeof schema !== "object" || schema === null) return void 0;
|
|
19297
19533
|
return schema.const;
|
|
19298
19534
|
}
|
|
19535
|
+
function isChoiceArray(property) {
|
|
19536
|
+
return property.type === "array" && Array.isArray(property.items?.enum);
|
|
19537
|
+
}
|
|
19538
|
+
function declarationOf(prop) {
|
|
19539
|
+
return normalizeNullableUnion(typeof prop === "object" && prop !== null ? prop : {});
|
|
19540
|
+
}
|
|
19299
19541
|
function schemaToForm(schema, toolName) {
|
|
19300
19542
|
const title = `Test Tool: ${toolName}`;
|
|
19301
19543
|
if (!schema) return {
|
|
@@ -19351,7 +19593,7 @@ function schemaToForm(schema, toolName) {
|
|
|
19351
19593
|
}
|
|
19352
19594
|
function decodeFormValues(schema, values) {
|
|
19353
19595
|
const { base, branches } = resolveRootUnion(schema ?? {});
|
|
19354
|
-
if (branches.length === 0) return applyConstants(base.properties ?? {}, values, requiredOf(base));
|
|
19596
|
+
if (branches.length === 0) return restoreChoices(base.properties ?? {}, applyConstants(base.properties ?? {}, values, requiredOf(base)), requiredOf(base));
|
|
19355
19597
|
const { variant, prefix } = generatedNames(base, branches);
|
|
19356
19598
|
const branchIndex = selectedBranchIndex(base, branches, values);
|
|
19357
19599
|
const branch = branches[branchIndex];
|
|
@@ -19361,7 +19603,9 @@ function decodeFormValues(schema, values) {
|
|
|
19361
19603
|
});
|
|
19362
19604
|
const decoded = Object.fromEntries([...Object.entries(values).filter(([name]) => !generated.has(name)), ...branchFields(base, branches, branchIndex).map((name) => [name, values[branchFieldName(prefix, branchIndex, name)]]).filter(([, value]) => value !== void 0)]);
|
|
19363
19605
|
/* v8 ignore next -- an offerable branch always carries properties */
|
|
19364
|
-
|
|
19606
|
+
const properties = branch.schema.properties ?? {};
|
|
19607
|
+
const required = requiredOf(branch.schema);
|
|
19608
|
+
return restoreChoices(properties, applyConstants(properties, decoded, required), required);
|
|
19365
19609
|
}
|
|
19366
19610
|
function selectedBranchIndex(base, branches, values) {
|
|
19367
19611
|
const { variant } = generatedNames(base, branches);
|
|
@@ -19373,12 +19617,24 @@ function applyConstants(properties, values, required) {
|
|
|
19373
19617
|
if (pinned.length === 0) return values;
|
|
19374
19618
|
return Object.fromEntries([...Object.entries(values), ...pinned.map(([name, schema]) => [name, constOf(schema)])]);
|
|
19375
19619
|
}
|
|
19620
|
+
function restoreChoices(properties, values, required) {
|
|
19621
|
+
const choiceFields = Object.entries(properties).map(([name, prop]) => [name, declarationOf(prop)]).filter(([name, property]) => isChoiceArray(property) && property.const === void 0 && Object.hasOwn(values, name) && Array.isArray(values[name]));
|
|
19622
|
+
if (choiceFields.length === 0) return values;
|
|
19623
|
+
const restored = new Map(choiceFields.map(([name, property]) => {
|
|
19624
|
+
const chosen = values[name];
|
|
19625
|
+
if (chosen.length === 0 && !required.includes(name)) return [name, void 0];
|
|
19626
|
+
/* v8 ignore next -- `isChoiceArray` guarantees `items.enum` above */
|
|
19627
|
+
const members = property.items?.enum ?? [];
|
|
19628
|
+
return [name, chosen.map((each) => memberForChoiceId(members, each))];
|
|
19629
|
+
}));
|
|
19630
|
+
return Object.fromEntries(Object.entries(values).map(([name, value]) => restored.has(name) ? [name, restored.get(name)] : [name, value]).filter(([, value]) => value !== void 0));
|
|
19631
|
+
}
|
|
19376
19632
|
function buildFields(schema, { optional = false } = {}) {
|
|
19377
19633
|
const fields = [];
|
|
19378
19634
|
const properties = schema.properties || {};
|
|
19379
19635
|
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
19380
19636
|
for (const [key, prop] of Object.entries(properties)) {
|
|
19381
|
-
const property =
|
|
19637
|
+
const property = declarationOf(prop);
|
|
19382
19638
|
const baseField = {
|
|
19383
19639
|
name: key,
|
|
19384
19640
|
label: property.title || key,
|
|
@@ -19399,12 +19655,18 @@ function buildFields(schema, { optional = false } = {}) {
|
|
|
19399
19655
|
});
|
|
19400
19656
|
continue;
|
|
19401
19657
|
}
|
|
19402
|
-
if (property
|
|
19403
|
-
|
|
19404
|
-
|
|
19405
|
-
|
|
19406
|
-
|
|
19407
|
-
|
|
19658
|
+
if (isChoiceArray(property)) {
|
|
19659
|
+
const multi = {
|
|
19660
|
+
type: MULTISELECT_FIELD_TYPE,
|
|
19661
|
+
...baseField,
|
|
19662
|
+
options: choiceOptions(property.items.enum, property.items.enumNames),
|
|
19663
|
+
...typeof property.minItems === "number" && { minItems: property.minItems },
|
|
19664
|
+
...typeof property.maxItems === "number" && { maxItems: property.maxItems },
|
|
19665
|
+
...Array.isArray(property.default) && { initialValue: choiceIds(property.items.enum, property.default) }
|
|
19666
|
+
};
|
|
19667
|
+
fields.push(multi);
|
|
19668
|
+
continue;
|
|
19669
|
+
} else if (isStringEnum(property.enum)) field = {
|
|
19408
19670
|
type: "select",
|
|
19409
19671
|
...baseField,
|
|
19410
19672
|
/* v8 ignore next -- guarded by `isStringEnum(property.enum)` above */
|
|
@@ -19464,16 +19726,95 @@ function missingRequiredFields(schema, decoded, rawValues = {}) {
|
|
|
19464
19726
|
return value === void 0;
|
|
19465
19727
|
});
|
|
19466
19728
|
}
|
|
19467
|
-
|
|
19468
|
-
|
|
19729
|
+
function selectionCountErrors(schema, decoded, rawValues = {}) {
|
|
19730
|
+
const { base, branches } = resolveRootUnion(schema ?? {});
|
|
19731
|
+
/* v8 ignore next -- an offerable branch always carries properties */
|
|
19732
|
+
const properties = (branches.length === 0 ? base : branches[selectedBranchIndex(base, branches, rawValues)].schema).properties ?? {};
|
|
19733
|
+
return Object.entries(properties).flatMap(([name, prop]) => {
|
|
19734
|
+
const value = Object.hasOwn(decoded, name) ? decoded[name] : void 0;
|
|
19735
|
+
if (!Array.isArray(value)) return [];
|
|
19736
|
+
const { minItems, maxItems } = declarationOf(prop);
|
|
19737
|
+
if (typeof minItems === "number" && value.length < minItems) return [`${name}: choose at least ${minItems}`];
|
|
19738
|
+
if (typeof maxItems === "number" && value.length > maxItems) return [`${name}: choose at most ${maxItems}`];
|
|
19739
|
+
return [];
|
|
19740
|
+
});
|
|
19741
|
+
}
|
|
19742
|
+
function MultiSelectInput({ field, value, onChange }) {
|
|
19743
|
+
const [cursor, setCursor] = useState(0);
|
|
19744
|
+
const selected = value ?? [];
|
|
19745
|
+
const count = field.options.length;
|
|
19746
|
+
useInput((input, key) => {
|
|
19747
|
+
if (key.upArrow) setCursor((current) => Math.max(0, current - 1));
|
|
19748
|
+
else if (key.downArrow) setCursor((current) => Math.min(count - 1, current + 1));
|
|
19749
|
+
else if (input === " ") {
|
|
19750
|
+
const option = field.options[cursor];
|
|
19751
|
+
if (option) onChange(toggleChoice(selected, option.value, field.options));
|
|
19752
|
+
}
|
|
19753
|
+
});
|
|
19754
|
+
const start = windowStart(cursor, count, 8);
|
|
19755
|
+
const hint = boundsHint(field.minItems, field.maxItems);
|
|
19756
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
19757
|
+
width: "100%",
|
|
19758
|
+
borderStyle: "round",
|
|
19759
|
+
flexDirection: "column",
|
|
19760
|
+
children: [
|
|
19761
|
+
field.options.slice(start, start + 8).map((option, offset) => {
|
|
19762
|
+
const active = start + offset === cursor;
|
|
19763
|
+
const checked = selected.includes(option.value);
|
|
19764
|
+
return /* @__PURE__ */ jsxs(Text, {
|
|
19765
|
+
color: active ? "blue" : void 0,
|
|
19766
|
+
children: [
|
|
19767
|
+
active ? "❯ " : " ",
|
|
19768
|
+
checked ? "[x] " : "[ ] ",
|
|
19769
|
+
option.label ?? option.value
|
|
19770
|
+
]
|
|
19771
|
+
}, option.value);
|
|
19772
|
+
}),
|
|
19773
|
+
count > 8 && /* @__PURE__ */ jsxs(Text, {
|
|
19774
|
+
dimColor: true,
|
|
19775
|
+
children: [
|
|
19776
|
+
start + 1,
|
|
19777
|
+
"-",
|
|
19778
|
+
start + 8,
|
|
19779
|
+
" of ",
|
|
19780
|
+
count
|
|
19781
|
+
]
|
|
19782
|
+
}),
|
|
19783
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
19784
|
+
dimColor: true,
|
|
19785
|
+
children: [
|
|
19786
|
+
"Up/Down to move, Space to toggle (",
|
|
19787
|
+
selected.length,
|
|
19788
|
+
" selected)",
|
|
19789
|
+
hint ? `. ${hint}` : ""
|
|
19790
|
+
]
|
|
19791
|
+
})
|
|
19792
|
+
]
|
|
19793
|
+
});
|
|
19794
|
+
}
|
|
19795
|
+
function isMultiSelectField(field) {
|
|
19796
|
+
return field.type === MULTISELECT_FIELD_TYPE;
|
|
19797
|
+
}
|
|
19798
|
+
function asSelection(value) {
|
|
19799
|
+
return Array.isArray(value) ? value.filter((each) => typeof each === "string") : void 0;
|
|
19800
|
+
}
|
|
19801
|
+
const FORM_FIELD_MANAGERS = [{
|
|
19802
|
+
type: MULTISELECT_FIELD_TYPE,
|
|
19803
|
+
renderField: (props) => isMultiSelectField(props.field) ? /* @__PURE__ */ jsx(MultiSelectInput, {
|
|
19804
|
+
field: props.field,
|
|
19805
|
+
value: asSelection(props.value),
|
|
19806
|
+
onChange: props.onChange
|
|
19807
|
+
}) : null,
|
|
19808
|
+
renderValue: (props) => isMultiSelectField(props.field) ? /* @__PURE__ */ jsx(Fragment, { children: selectionLabel(props.field.options, asSelection(props.value)) }) : null
|
|
19809
|
+
}];
|
|
19810
|
+
// src/utils/formHeader.ts
|
|
19469
19811
|
function untitledForm(form) {
|
|
19470
19812
|
return {
|
|
19471
19813
|
...form,
|
|
19472
19814
|
title: void 0
|
|
19473
19815
|
};
|
|
19474
19816
|
}
|
|
19475
|
-
|
|
19476
|
-
//#region ../../core/mcp/resultFile.ts
|
|
19817
|
+
// ../../core/mcp/resultFile.ts
|
|
19477
19818
|
var RawResultUnavailableError = class extends Error {
|
|
19478
19819
|
method;
|
|
19479
19820
|
binaryCount;
|
|
@@ -19519,8 +19860,7 @@ function renderResultForFile(result, method, format) {
|
|
|
19519
19860
|
function renderedByteLength(data) {
|
|
19520
19861
|
return typeof data === "string" ? new TextEncoder().encode(data).length : data.length;
|
|
19521
19862
|
}
|
|
19522
|
-
|
|
19523
|
-
//#region src/utils/saveResult.ts
|
|
19863
|
+
// src/utils/saveResult.ts
|
|
19524
19864
|
function fileSafe(name) {
|
|
19525
19865
|
const safe = name.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
19526
19866
|
return safe === "" ? "tool" : safe;
|
|
@@ -19564,8 +19904,7 @@ async function writeResult(result, path, format, cwd) {
|
|
|
19564
19904
|
function errorMessage(err) {
|
|
19565
19905
|
return err instanceof Error ? err.message : String(err);
|
|
19566
19906
|
}
|
|
19567
|
-
|
|
19568
|
-
//#region src/components/SaveResultBar.tsx
|
|
19907
|
+
// src/components/SaveResultBar.tsx
|
|
19569
19908
|
function SaveResultBar({ prompt, status }) {
|
|
19570
19909
|
if (prompt) return /* @__PURE__ */ jsxs(Box, {
|
|
19571
19910
|
flexShrink: 0,
|
|
@@ -19600,9 +19939,8 @@ function SaveResultBar({ prompt, status }) {
|
|
|
19600
19939
|
});
|
|
19601
19940
|
return null;
|
|
19602
19941
|
}
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRecoveryRequired }) {
|
|
19942
|
+
// src/components/ToolTestModal.tsx
|
|
19943
|
+
function ToolTestModal({ tool, inspectorClient, width, height, onClose, inputActive = true, onAuthRecoveryRequired }) {
|
|
19606
19944
|
const [state, setState] = useState("form");
|
|
19607
19945
|
const [result, setResult] = useState(null);
|
|
19608
19946
|
const [savePrompt, setSavePromptState] = useState(null);
|
|
@@ -19676,7 +20014,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19676
20014
|
}
|
|
19677
20015
|
}
|
|
19678
20016
|
};
|
|
19679
|
-
useInput((input, key) => handleInputRef.current(input, key), { isActive:
|
|
20017
|
+
useInput((input, key) => handleInputRef.current(input, key), { isActive: inputActive });
|
|
19680
20018
|
const openSavePrompt = () => {
|
|
19681
20019
|
if (!result?.callResult) {
|
|
19682
20020
|
setSaveStatus({
|
|
@@ -19748,6 +20086,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19748
20086
|
}
|
|
19749
20087
|
};
|
|
19750
20088
|
const handleFormSubmit = async (rawValues) => {
|
|
20089
|
+
if (!inputActive) return;
|
|
19751
20090
|
if (!inspectorClient || !tool) return;
|
|
19752
20091
|
const values = decodeFormValues(inputSchema, rawValues);
|
|
19753
20092
|
const missing = missingRequiredFields(inputSchema, values, rawValues);
|
|
@@ -19761,6 +20100,17 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19761
20100
|
setState("results");
|
|
19762
20101
|
return;
|
|
19763
20102
|
}
|
|
20103
|
+
const outOfBounds = selectionCountErrors(inputSchema, values, rawValues);
|
|
20104
|
+
if (outOfBounds.length > 0) {
|
|
20105
|
+
setResult({
|
|
20106
|
+
input: values,
|
|
20107
|
+
output: null,
|
|
20108
|
+
error: `Invalid argument${outOfBounds.length > 1 ? "s" : ""}: ${outOfBounds.join("; ")}`,
|
|
20109
|
+
duration: 0
|
|
20110
|
+
});
|
|
20111
|
+
setState("results");
|
|
20112
|
+
return;
|
|
20113
|
+
}
|
|
19764
20114
|
setState("loading");
|
|
19765
20115
|
const startTime = Date.now();
|
|
19766
20116
|
try {
|
|
@@ -19851,6 +20201,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19851
20201
|
width: "100%",
|
|
19852
20202
|
children: /* @__PURE__ */ jsx(Form, {
|
|
19853
20203
|
form: untitledForm(formStructure),
|
|
20204
|
+
customManagers: FORM_FIELD_MANAGERS,
|
|
19854
20205
|
onSubmit: (value) => void handleFormSubmit(value)
|
|
19855
20206
|
})
|
|
19856
20207
|
}),
|
|
@@ -19958,8 +20309,7 @@ function ToolTestModal({ tool, inspectorClient, width, height, onClose, onAuthRe
|
|
|
19958
20309
|
})
|
|
19959
20310
|
});
|
|
19960
20311
|
}
|
|
19961
|
-
|
|
19962
|
-
//#region src/utils/uriTemplateToForm.ts
|
|
20312
|
+
// src/utils/uriTemplateToForm.ts
|
|
19963
20313
|
function uriTemplateToForm(uriTemplate, templateName) {
|
|
19964
20314
|
let fields = [];
|
|
19965
20315
|
try {
|
|
@@ -19983,15 +20333,14 @@ function uriTemplateToForm(uriTemplate, templateName) {
|
|
|
19983
20333
|
sections
|
|
19984
20334
|
};
|
|
19985
20335
|
}
|
|
19986
|
-
|
|
19987
|
-
//#region src/components/ResourceTestModal.tsx
|
|
20336
|
+
// src/components/ResourceTestModal.tsx
|
|
19988
20337
|
function getErrorMessage$1(error) {
|
|
19989
20338
|
if (error instanceof Error) return error.message;
|
|
19990
20339
|
if (typeof error === "string") return error;
|
|
19991
20340
|
if (error && typeof error === "object" && "message" in error) return String(error.message);
|
|
19992
20341
|
return "Unknown error";
|
|
19993
20342
|
}
|
|
19994
|
-
function ResourceTestModal({ template, inspectorClient, width, height, onClose, onAuthRecoveryRequired }) {
|
|
20343
|
+
function ResourceTestModal({ template, inspectorClient, width, height, onClose, inputActive = true, onAuthRecoveryRequired }) {
|
|
19995
20344
|
const [state, setState] = useState("form");
|
|
19996
20345
|
const [result, setResult] = useState(null);
|
|
19997
20346
|
const scrollViewRef = React.useRef(null);
|
|
@@ -20038,8 +20387,9 @@ function ResourceTestModal({ template, inspectorClient, width, height, onClose,
|
|
|
20038
20387
|
scrollViewRef.current?.scrollBy(-viewportHeight);
|
|
20039
20388
|
}
|
|
20040
20389
|
}
|
|
20041
|
-
}, { isActive:
|
|
20390
|
+
}, { isActive: inputActive });
|
|
20042
20391
|
const handleFormSubmit = async (values) => {
|
|
20392
|
+
if (!inputActive) return;
|
|
20043
20393
|
if (!inspectorClient || !template) return;
|
|
20044
20394
|
const unmetGroups = unmetRequiredGroups(requiredGroups(template.uriTemplate), values);
|
|
20045
20395
|
if (unmetGroups.length > 0) {
|
|
@@ -20267,8 +20617,7 @@ function ResourceTestModal({ template, inspectorClient, width, height, onClose,
|
|
|
20267
20617
|
})
|
|
20268
20618
|
});
|
|
20269
20619
|
}
|
|
20270
|
-
|
|
20271
|
-
//#region src/utils/promptArgsToForm.ts
|
|
20620
|
+
// src/utils/promptArgsToForm.ts
|
|
20272
20621
|
function promptArgsToForm(promptArguments, promptName) {
|
|
20273
20622
|
const fields = [];
|
|
20274
20623
|
if (!promptArguments || promptArguments.length === 0) return {
|
|
@@ -20297,15 +20646,14 @@ function promptArgsToForm(promptArguments, promptName) {
|
|
|
20297
20646
|
sections
|
|
20298
20647
|
};
|
|
20299
20648
|
}
|
|
20300
|
-
|
|
20301
|
-
//#region src/components/PromptTestModal.tsx
|
|
20649
|
+
// src/components/PromptTestModal.tsx
|
|
20302
20650
|
function getErrorMessage(error) {
|
|
20303
20651
|
if (error instanceof Error) return error.message;
|
|
20304
20652
|
if (typeof error === "string") return error;
|
|
20305
20653
|
if (error && typeof error === "object" && "message" in error) return String(error.message);
|
|
20306
20654
|
return "Unknown error";
|
|
20307
20655
|
}
|
|
20308
|
-
function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAuthRecoveryRequired }) {
|
|
20656
|
+
function PromptTestModal({ prompt, inspectorClient, width, height, onClose, inputActive = true, onAuthRecoveryRequired }) {
|
|
20309
20657
|
const [state, setState] = useState("form");
|
|
20310
20658
|
const [result, setResult] = useState(null);
|
|
20311
20659
|
const scrollViewRef = React.useRef(null);
|
|
@@ -20352,8 +20700,9 @@ function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAu
|
|
|
20352
20700
|
scrollViewRef.current?.scrollBy(-viewportHeight);
|
|
20353
20701
|
}
|
|
20354
20702
|
}
|
|
20355
|
-
}, { isActive:
|
|
20703
|
+
}, { isActive: inputActive });
|
|
20356
20704
|
const handleFormSubmit = async (values) => {
|
|
20705
|
+
if (!inputActive) return;
|
|
20357
20706
|
if (!inspectorClient || !prompt) return;
|
|
20358
20707
|
setState("loading");
|
|
20359
20708
|
const startTime = Date.now();
|
|
@@ -20552,9 +20901,8 @@ function PromptTestModal({ prompt, inspectorClient, width, height, onClose, onAu
|
|
|
20552
20901
|
})
|
|
20553
20902
|
});
|
|
20554
20903
|
}
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
function DetailsModal({ title, content, width, height, onClose, copyText }) {
|
|
20904
|
+
// src/components/DetailsModal.tsx
|
|
20905
|
+
function DetailsModal({ title, content, width, height, onClose, inputActive = true, copyText }) {
|
|
20558
20906
|
const scrollViewRef = useRef(null);
|
|
20559
20907
|
const { handleCopyKey, status: copyStatus } = useCopyKeys(copyText, "details");
|
|
20560
20908
|
const [terminalDimensions, setTerminalDimensions] = React.useState({
|
|
@@ -20586,7 +20934,7 @@ function DetailsModal({ title, content, width, height, onClose, copyText }) {
|
|
|
20586
20934
|
const viewportHeight = scrollViewRef.current?.getViewportHeight() || 1;
|
|
20587
20935
|
scrollViewRef.current?.scrollBy(-viewportHeight);
|
|
20588
20936
|
}
|
|
20589
|
-
}, { isActive:
|
|
20937
|
+
}, { isActive: inputActive });
|
|
20590
20938
|
const modalWidth = terminalDimensions.width - 2;
|
|
20591
20939
|
const modalHeight = terminalDimensions.height - 2;
|
|
20592
20940
|
return /* @__PURE__ */ jsx(Box, {
|
|
@@ -20643,8 +20991,7 @@ function DetailsModal({ title, content, width, height, onClose, copyText }) {
|
|
|
20643
20991
|
})
|
|
20644
20992
|
});
|
|
20645
20993
|
}
|
|
20646
|
-
|
|
20647
|
-
//#region src/utils/keybindings.ts
|
|
20994
|
+
// src/utils/keybindings.ts
|
|
20648
20995
|
function tabAcceleratorBinding(visible) {
|
|
20649
20996
|
return {
|
|
20650
20997
|
keys: visible.map((tab) => tab.accelerator).join(" "),
|
|
@@ -20891,10 +21238,9 @@ function keyColumnWidth(sections) {
|
|
|
20891
21238
|
for (const section of sections) for (const binding of section.bindings) width = Math.max(width, binding.keys.length);
|
|
20892
21239
|
return width;
|
|
20893
21240
|
}
|
|
20894
|
-
|
|
20895
|
-
//#region src/components/HelpOverlay.tsx
|
|
21241
|
+
// src/components/HelpOverlay.tsx
|
|
20896
21242
|
const COLUMN_GAP = 2;
|
|
20897
|
-
function HelpOverlay({ sections, width, height, onClose }) {
|
|
21243
|
+
function HelpOverlay({ sections, width, height, onClose, inputActive = true }) {
|
|
20898
21244
|
const scrollViewRef = useRef(null);
|
|
20899
21245
|
const keysWidth = keyColumnWidth(sections) + COLUMN_GAP;
|
|
20900
21246
|
useInput((input, key) => {
|
|
@@ -20904,7 +21250,7 @@ function HelpOverlay({ sections, width, height, onClose }) {
|
|
|
20904
21250
|
else if (key.upArrow) view?.scrollBy(-1);
|
|
20905
21251
|
else if (key.pageDown) view?.scrollBy(view.getViewportHeight());
|
|
20906
21252
|
else if (key.pageUp) view?.scrollBy(-view.getViewportHeight());
|
|
20907
|
-
});
|
|
21253
|
+
}, { isActive: inputActive });
|
|
20908
21254
|
return /* @__PURE__ */ jsx(Box, {
|
|
20909
21255
|
position: "absolute",
|
|
20910
21256
|
width,
|
|
@@ -20963,8 +21309,7 @@ function HelpOverlay({ sections, width, height, onClose }) {
|
|
|
20963
21309
|
})
|
|
20964
21310
|
});
|
|
20965
21311
|
}
|
|
20966
|
-
|
|
20967
|
-
//#region src/components/TasksTab.tsx
|
|
21312
|
+
// src/components/TasksTab.tsx
|
|
20968
21313
|
const STATUS_STYLE = {
|
|
20969
21314
|
working: {
|
|
20970
21315
|
glyph: "◐",
|
|
@@ -21316,8 +21661,7 @@ function subscribableResources(resources, subscriptions) {
|
|
|
21316
21661
|
}
|
|
21317
21662
|
return rows;
|
|
21318
21663
|
}
|
|
21319
|
-
|
|
21320
|
-
//#region src/components/SubscriptionsTab.tsx
|
|
21664
|
+
// src/components/SubscriptionsTab.tsx
|
|
21321
21665
|
const STREAM_STATUS_TEXT = {
|
|
21322
21666
|
connecting: {
|
|
21323
21667
|
text: "connecting…",
|
|
@@ -21597,8 +21941,7 @@ function SubscriptionsTab({ resources, subscriptions, streamState, messages, ins
|
|
|
21597
21941
|
})]
|
|
21598
21942
|
});
|
|
21599
21943
|
}
|
|
21600
|
-
|
|
21601
|
-
//#region src/components/RootsModal.tsx
|
|
21944
|
+
// src/components/RootsModal.tsx
|
|
21602
21945
|
const ADD_ROOT_FORM = {
|
|
21603
21946
|
title: "Add Root",
|
|
21604
21947
|
sections: [{
|
|
@@ -21624,7 +21967,7 @@ function rootFromForm(values) {
|
|
|
21624
21967
|
name
|
|
21625
21968
|
} : { uri };
|
|
21626
21969
|
}
|
|
21627
|
-
function RootsModal({ roots, inspectorClient, connected, width, height, onClose }) {
|
|
21970
|
+
function RootsModal({ roots, inspectorClient, connected, width, height, onClose, inputActive = true }) {
|
|
21628
21971
|
const [mode, setMode] = useState("list");
|
|
21629
21972
|
const [error, setError] = useState(null);
|
|
21630
21973
|
const [saving, setSaving] = useState(false);
|
|
@@ -21649,6 +21992,7 @@ function RootsModal({ roots, inspectorClient, connected, width, height, onClose
|
|
|
21649
21992
|
}
|
|
21650
21993
|
};
|
|
21651
21994
|
const handleSubmit = (values) => {
|
|
21995
|
+
if (!inputActive) return;
|
|
21652
21996
|
const root = rootFromForm(values);
|
|
21653
21997
|
if ("error" in root) {
|
|
21654
21998
|
setError(root.error);
|
|
@@ -21680,7 +22024,7 @@ function RootsModal({ roots, inspectorClient, connected, width, height, onClose
|
|
|
21680
22024
|
}
|
|
21681
22025
|
save(roots.filter((_, i) => i !== selectedIndex));
|
|
21682
22026
|
}
|
|
21683
|
-
});
|
|
22027
|
+
}, { isActive: inputActive });
|
|
21684
22028
|
return /* @__PURE__ */ jsx(Box, {
|
|
21685
22029
|
position: "absolute",
|
|
21686
22030
|
width,
|
|
@@ -21791,8 +22135,468 @@ function RootsModal({ roots, inspectorClient, connected, width, height, onClose
|
|
|
21791
22135
|
})
|
|
21792
22136
|
});
|
|
21793
22137
|
}
|
|
21794
|
-
|
|
21795
|
-
|
|
22138
|
+
// src/utils/pendingRequests.ts
|
|
22139
|
+
const SAMPLING_STOP_REASONS = [
|
|
22140
|
+
"endTurn",
|
|
22141
|
+
"stopSequence",
|
|
22142
|
+
"maxTokens"
|
|
22143
|
+
];
|
|
22144
|
+
const DEFAULT_SAMPLING_MODEL = "stub-model";
|
|
22145
|
+
const SAMPLING_RESPONSE_FORM = { sections: [{
|
|
22146
|
+
title: "Response",
|
|
22147
|
+
fields: [
|
|
22148
|
+
{
|
|
22149
|
+
type: "string",
|
|
22150
|
+
name: "text",
|
|
22151
|
+
label: "Response text"
|
|
22152
|
+
},
|
|
22153
|
+
{
|
|
22154
|
+
type: "string",
|
|
22155
|
+
name: "model",
|
|
22156
|
+
label: "Model",
|
|
22157
|
+
required: true,
|
|
22158
|
+
initialValue: DEFAULT_SAMPLING_MODEL
|
|
22159
|
+
},
|
|
22160
|
+
{
|
|
22161
|
+
type: "select",
|
|
22162
|
+
name: "stopReason",
|
|
22163
|
+
label: "Stop reason",
|
|
22164
|
+
required: true,
|
|
22165
|
+
initialValue: "endTurn",
|
|
22166
|
+
options: SAMPLING_STOP_REASONS.map((reason) => ({
|
|
22167
|
+
label: reason,
|
|
22168
|
+
value: reason
|
|
22169
|
+
}))
|
|
22170
|
+
}
|
|
22171
|
+
]
|
|
22172
|
+
}] };
|
|
22173
|
+
function samplingResultFromForm(values) {
|
|
22174
|
+
const text = typeof values.text === "string" ? values.text : "";
|
|
22175
|
+
return {
|
|
22176
|
+
role: "assistant",
|
|
22177
|
+
model: typeof values.model === "string" && values.model.trim() !== "" ? values.model.trim() : DEFAULT_SAMPLING_MODEL,
|
|
22178
|
+
stopReason: typeof values.stopReason === "string" ? values.stopReason : "endTurn",
|
|
22179
|
+
content: {
|
|
22180
|
+
type: "text",
|
|
22181
|
+
text
|
|
22182
|
+
}
|
|
22183
|
+
};
|
|
22184
|
+
}
|
|
22185
|
+
function describeBlock(block) {
|
|
22186
|
+
if (typeof block !== "object" || block === null) return String(block);
|
|
22187
|
+
const typed = block;
|
|
22188
|
+
if (typed.type === "text" && typeof typed.text === "string") return typed.text;
|
|
22189
|
+
if (typeof typed.mimeType === "string") return `[${String(typed.type)}: ${typed.mimeType}]`;
|
|
22190
|
+
if (typeof typed.name === "string") return `[${String(typed.type)}: ${typed.name}]`;
|
|
22191
|
+
return `[${String(typed.type ?? "unknown")}]`;
|
|
22192
|
+
}
|
|
22193
|
+
function describeSamplingRequest(params) {
|
|
22194
|
+
const lines = [];
|
|
22195
|
+
if (params.systemPrompt) lines.push(`System prompt: ${params.systemPrompt}`);
|
|
22196
|
+
lines.push(`Max tokens: ${params.maxTokens}`);
|
|
22197
|
+
const hints = (params.modelPreferences?.hints ?? []).map((hint) => hint.name).filter((name) => typeof name === "string");
|
|
22198
|
+
if (hints.length > 0) lines.push(`Model hints: ${hints.join(", ")}`);
|
|
22199
|
+
lines.push("");
|
|
22200
|
+
for (const message of params.messages) {
|
|
22201
|
+
const [first = "", ...rest] = (Array.isArray(message.content) ? message.content : [message.content]).map(describeBlock).join(" ").split("\n");
|
|
22202
|
+
lines.push(`${message.role}: ${first}`);
|
|
22203
|
+
for (const line of rest) lines.push(` ${line}`);
|
|
22204
|
+
}
|
|
22205
|
+
return lines;
|
|
22206
|
+
}
|
|
22207
|
+
function constOptions(members) {
|
|
22208
|
+
if (!Array.isArray(members) || members.length === 0) return void 0;
|
|
22209
|
+
const values = [];
|
|
22210
|
+
const names = [];
|
|
22211
|
+
for (const member of members) {
|
|
22212
|
+
if (typeof member !== "object" || member === null) return void 0;
|
|
22213
|
+
const { const: value, title } = member;
|
|
22214
|
+
if (typeof value !== "string") return void 0;
|
|
22215
|
+
values.push(value);
|
|
22216
|
+
names.push(typeof title === "string" ? title : value);
|
|
22217
|
+
}
|
|
22218
|
+
return {
|
|
22219
|
+
values,
|
|
22220
|
+
names
|
|
22221
|
+
};
|
|
22222
|
+
}
|
|
22223
|
+
function normalizeElicitationSchema(schema) {
|
|
22224
|
+
const properties = Object.fromEntries(Object.entries(schema.properties).map(([name, property]) => {
|
|
22225
|
+
const { oneOf, items, ...rest } = property;
|
|
22226
|
+
const single = constOptions(oneOf);
|
|
22227
|
+
if (single) return [name, {
|
|
22228
|
+
...rest,
|
|
22229
|
+
enum: single.values,
|
|
22230
|
+
enumNames: single.names
|
|
22231
|
+
}];
|
|
22232
|
+
const multi = constOptions(items?.anyOf);
|
|
22233
|
+
if (multi) return [name, {
|
|
22234
|
+
...rest,
|
|
22235
|
+
items: {
|
|
22236
|
+
enum: multi.values,
|
|
22237
|
+
enumNames: multi.names
|
|
22238
|
+
}
|
|
22239
|
+
}];
|
|
22240
|
+
return [name, property];
|
|
22241
|
+
}));
|
|
22242
|
+
return {
|
|
22243
|
+
...schema,
|
|
22244
|
+
properties
|
|
22245
|
+
};
|
|
22246
|
+
}
|
|
22247
|
+
function elicitationForm(schema) {
|
|
22248
|
+
const [first, ...rest] = schemaToForm(normalizeElicitationSchema(schema), "elicitation").sections;
|
|
22249
|
+
return { sections: [{
|
|
22250
|
+
...first,
|
|
22251
|
+
title: "Response"
|
|
22252
|
+
}, ...rest] };
|
|
22253
|
+
}
|
|
22254
|
+
function elicitationContentFromForm(schema, rawValues) {
|
|
22255
|
+
const normalized = normalizeElicitationSchema(schema);
|
|
22256
|
+
const decoded = decodeFormValues(normalized, rawValues);
|
|
22257
|
+
const missing = missingRequiredFields(normalized, decoded, rawValues);
|
|
22258
|
+
if (missing.length > 0) return { missing };
|
|
22259
|
+
const invalid = selectionCountErrors(normalized, decoded, rawValues);
|
|
22260
|
+
if (invalid.length > 0) return { invalid };
|
|
22261
|
+
return { result: {
|
|
22262
|
+
action: "accept",
|
|
22263
|
+
content: Object.fromEntries(Object.entries(decoded).filter(([, value]) => value !== void 0 && value !== null).map(([name, value]) => {
|
|
22264
|
+
return [name, normalized.properties[name]?.type === "array" && typeof value === "string" ? [value] : value];
|
|
22265
|
+
}))
|
|
22266
|
+
} };
|
|
22267
|
+
}
|
|
22268
|
+
function messageBoxHeight(message, columns, terminalRows) {
|
|
22269
|
+
const perRow = Math.max(1, columns);
|
|
22270
|
+
const wrapped = message.split("\n").reduce((rows, line) => rows + Math.max(1, Math.ceil(line.length / perRow)), 0);
|
|
22271
|
+
return Math.max(1, Math.min(wrapped, Math.floor(terminalRows / 3)));
|
|
22272
|
+
}
|
|
22273
|
+
function elicitationUrlRefusal(url) {
|
|
22274
|
+
try {
|
|
22275
|
+
const { protocol } = new URL(url);
|
|
22276
|
+
if (protocol === "http:" || protocol === "https:") return void 0;
|
|
22277
|
+
} catch {}
|
|
22278
|
+
return "Refusing to open this URL: only http: and https: URLs can be opened from an elicitation request.";
|
|
22279
|
+
}
|
|
22280
|
+
// src/components/PendingRequestModal.tsx
|
|
22281
|
+
function useSettle(onError) {
|
|
22282
|
+
const busyRef = useRef(false);
|
|
22283
|
+
return (action) => {
|
|
22284
|
+
if (busyRef.current) return;
|
|
22285
|
+
busyRef.current = true;
|
|
22286
|
+
action().catch((err) => {
|
|
22287
|
+
busyRef.current = false;
|
|
22288
|
+
onError(errorMessage$1(err));
|
|
22289
|
+
});
|
|
22290
|
+
};
|
|
22291
|
+
}
|
|
22292
|
+
function useDismissPrompt() {
|
|
22293
|
+
const [confirming, setConfirming] = useState(false);
|
|
22294
|
+
const openRef = useRef(false);
|
|
22295
|
+
const closingRef = useRef(false);
|
|
22296
|
+
return {
|
|
22297
|
+
confirming,
|
|
22298
|
+
isOpen: () => openRef.current,
|
|
22299
|
+
open: () => {
|
|
22300
|
+
openRef.current = true;
|
|
22301
|
+
setConfirming(true);
|
|
22302
|
+
},
|
|
22303
|
+
close: () => {
|
|
22304
|
+
openRef.current = false;
|
|
22305
|
+
closingRef.current = true;
|
|
22306
|
+
setConfirming(false);
|
|
22307
|
+
setTimeout(() => {
|
|
22308
|
+
closingRef.current = false;
|
|
22309
|
+
}, 0);
|
|
22310
|
+
},
|
|
22311
|
+
submitBlocked: () => openRef.current || closingRef.current
|
|
22312
|
+
};
|
|
22313
|
+
}
|
|
22314
|
+
function originNote(origin, taskId) {
|
|
22315
|
+
if (origin === "task-input-required") return `Requested by task ${taskId ?? "(unknown)"} (input_required)`;
|
|
22316
|
+
if (origin === "input-required") return "Requested mid-call (input_required round)";
|
|
22317
|
+
return null;
|
|
22318
|
+
}
|
|
22319
|
+
function ModalFrame({ title, hint, queueLabel, note, status, width, height, children }) {
|
|
22320
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
22321
|
+
position: "absolute",
|
|
22322
|
+
width,
|
|
22323
|
+
height,
|
|
22324
|
+
flexDirection: "column",
|
|
22325
|
+
justifyContent: "center",
|
|
22326
|
+
alignItems: "center",
|
|
22327
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
22328
|
+
width: width - 2,
|
|
22329
|
+
height: height - 2,
|
|
22330
|
+
borderStyle: "single",
|
|
22331
|
+
borderColor: "yellow",
|
|
22332
|
+
flexDirection: "column",
|
|
22333
|
+
paddingX: 1,
|
|
22334
|
+
paddingY: 1,
|
|
22335
|
+
backgroundColor: "black",
|
|
22336
|
+
children: [
|
|
22337
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
22338
|
+
flexShrink: 0,
|
|
22339
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
22340
|
+
bold: true,
|
|
22341
|
+
color: "yellow",
|
|
22342
|
+
children: title
|
|
22343
|
+
}), queueLabel && /* @__PURE__ */ jsxs(Text, {
|
|
22344
|
+
dimColor: true,
|
|
22345
|
+
children: [
|
|
22346
|
+
" (",
|
|
22347
|
+
queueLabel,
|
|
22348
|
+
")"
|
|
22349
|
+
]
|
|
22350
|
+
})]
|
|
22351
|
+
}),
|
|
22352
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22353
|
+
flexShrink: 0,
|
|
22354
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22355
|
+
dimColor: true,
|
|
22356
|
+
children: hint
|
|
22357
|
+
})
|
|
22358
|
+
}),
|
|
22359
|
+
note && /* @__PURE__ */ jsx(Box, {
|
|
22360
|
+
flexShrink: 0,
|
|
22361
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22362
|
+
dimColor: true,
|
|
22363
|
+
children: note
|
|
22364
|
+
})
|
|
22365
|
+
}),
|
|
22366
|
+
status && /* @__PURE__ */ jsx(Box, {
|
|
22367
|
+
flexShrink: 0,
|
|
22368
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22369
|
+
color: "red",
|
|
22370
|
+
children: status
|
|
22371
|
+
})
|
|
22372
|
+
}),
|
|
22373
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22374
|
+
flexGrow: 1,
|
|
22375
|
+
flexDirection: "column",
|
|
22376
|
+
overflow: "hidden",
|
|
22377
|
+
marginTop: 1,
|
|
22378
|
+
children
|
|
22379
|
+
})
|
|
22380
|
+
]
|
|
22381
|
+
})
|
|
22382
|
+
});
|
|
22383
|
+
}
|
|
22384
|
+
function DismissPrompt({ choices }) {
|
|
22385
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
22386
|
+
flexShrink: 0,
|
|
22387
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22388
|
+
color: "yellow",
|
|
22389
|
+
children: choices
|
|
22390
|
+
})
|
|
22391
|
+
});
|
|
22392
|
+
}
|
|
22393
|
+
function SamplingRequest({ sample, queueLabel, width, height }) {
|
|
22394
|
+
const [status, setStatus] = useState(null);
|
|
22395
|
+
const settle = useSettle(setStatus);
|
|
22396
|
+
const prompt = useDismissPrompt();
|
|
22397
|
+
const scrollViewRef = useRef(null);
|
|
22398
|
+
useInput((input, key) => {
|
|
22399
|
+
if (prompt.isOpen()) {
|
|
22400
|
+
prompt.close();
|
|
22401
|
+
if (input === "r") settle(() => sample.reject(/* @__PURE__ */ new Error("Sampling request rejected by user.")));
|
|
22402
|
+
return;
|
|
22403
|
+
}
|
|
22404
|
+
if (key.escape) prompt.open();
|
|
22405
|
+
else if (key.pageDown) scrollViewRef.current?.scrollBy(1);
|
|
22406
|
+
else if (key.pageUp) scrollViewRef.current?.scrollBy(-1);
|
|
22407
|
+
});
|
|
22408
|
+
const summaryHeight = Math.max(3, Math.floor((height - 8) * .4));
|
|
22409
|
+
return /* @__PURE__ */ jsxs(ModalFrame, {
|
|
22410
|
+
title: "Sampling request",
|
|
22411
|
+
hint: "(Enter on Submit to approve, ESC to reject, PgUp/PgDn to scroll)",
|
|
22412
|
+
queueLabel,
|
|
22413
|
+
note: originNote(sample.origin, sample.taskId),
|
|
22414
|
+
status,
|
|
22415
|
+
width,
|
|
22416
|
+
height,
|
|
22417
|
+
children: [
|
|
22418
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22419
|
+
height: summaryHeight,
|
|
22420
|
+
flexShrink: 0,
|
|
22421
|
+
flexDirection: "column",
|
|
22422
|
+
overflow: "hidden",
|
|
22423
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
22424
|
+
ref: scrollViewRef,
|
|
22425
|
+
children: describeSamplingRequest(sample.request.params).map((line, idx) => /* @__PURE__ */ jsx(Text, { children: line || " " }, idx))
|
|
22426
|
+
})
|
|
22427
|
+
}),
|
|
22428
|
+
prompt.confirming && /* @__PURE__ */ jsx(DismissPrompt, { choices: "Reject this sampling request? r: reject any other key: back" }),
|
|
22429
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22430
|
+
flexGrow: 1,
|
|
22431
|
+
width: "100%",
|
|
22432
|
+
children: /* @__PURE__ */ jsx(Form, {
|
|
22433
|
+
form: SAMPLING_RESPONSE_FORM,
|
|
22434
|
+
onSubmit: (values) => {
|
|
22435
|
+
if (prompt.submitBlocked()) return;
|
|
22436
|
+
settle(() => sample.respond(samplingResultFromForm(values)));
|
|
22437
|
+
}
|
|
22438
|
+
})
|
|
22439
|
+
})
|
|
22440
|
+
]
|
|
22441
|
+
});
|
|
22442
|
+
}
|
|
22443
|
+
function settleElicitation(elicitation, result, inspectorClient) {
|
|
22444
|
+
if (result.action === "cancel" && elicitation.origin === "task-input-required" && elicitation.taskId && inspectorClient) return inspectorClient.cancelRequestorTask(elicitation.taskId);
|
|
22445
|
+
return elicitation.respond(result);
|
|
22446
|
+
}
|
|
22447
|
+
function ElicitationFormRequest({ elicitation, params, inspectorClient, queueLabel, width, height }) {
|
|
22448
|
+
const [status, setStatus] = useState(null);
|
|
22449
|
+
const settleWith = useSettle(setStatus);
|
|
22450
|
+
const prompt = useDismissPrompt();
|
|
22451
|
+
const messageRef = useRef(null);
|
|
22452
|
+
const [form] = useState(() => elicitationForm(params.requestedSchema));
|
|
22453
|
+
const settle = (result) => settleWith(() => settleElicitation(elicitation, result, inspectorClient));
|
|
22454
|
+
useInput((input, key) => {
|
|
22455
|
+
if (prompt.isOpen()) {
|
|
22456
|
+
prompt.close();
|
|
22457
|
+
if (input === "d") settle({ action: "decline" });
|
|
22458
|
+
else if (input === "c") settle({ action: "cancel" });
|
|
22459
|
+
return;
|
|
22460
|
+
}
|
|
22461
|
+
if (key.escape) prompt.open();
|
|
22462
|
+
else if (key.pageDown) messageRef.current?.scrollBy(1);
|
|
22463
|
+
else if (key.pageUp) messageRef.current?.scrollBy(-1);
|
|
22464
|
+
});
|
|
22465
|
+
const handleSubmit = (values) => {
|
|
22466
|
+
if (prompt.submitBlocked()) return;
|
|
22467
|
+
const outcome = elicitationContentFromForm(params.requestedSchema, values);
|
|
22468
|
+
if ("missing" in outcome) {
|
|
22469
|
+
setStatus(`Missing required field${outcome.missing.length > 1 ? "s" : ""}: ${outcome.missing.join(", ")}`);
|
|
22470
|
+
return;
|
|
22471
|
+
}
|
|
22472
|
+
if ("invalid" in outcome) {
|
|
22473
|
+
setStatus(`Invalid field${outcome.invalid.length > 1 ? "s" : ""}: ${outcome.invalid.join("; ")}`);
|
|
22474
|
+
return;
|
|
22475
|
+
}
|
|
22476
|
+
settle(outcome.result);
|
|
22477
|
+
};
|
|
22478
|
+
return /* @__PURE__ */ jsxs(ModalFrame, {
|
|
22479
|
+
title: "Elicitation request",
|
|
22480
|
+
hint: "(Enter on Submit to accept, ESC to decline or cancel, PgUp/PgDn to scroll)",
|
|
22481
|
+
queueLabel,
|
|
22482
|
+
note: originNote(elicitation.origin, elicitation.taskId),
|
|
22483
|
+
status,
|
|
22484
|
+
width,
|
|
22485
|
+
height,
|
|
22486
|
+
children: [
|
|
22487
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22488
|
+
height: messageBoxHeight(params.message, width - 6, height),
|
|
22489
|
+
flexShrink: 0,
|
|
22490
|
+
flexDirection: "column",
|
|
22491
|
+
overflow: "hidden",
|
|
22492
|
+
marginBottom: 1,
|
|
22493
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
22494
|
+
ref: messageRef,
|
|
22495
|
+
children: /* @__PURE__ */ jsx(Text, { children: params.message })
|
|
22496
|
+
})
|
|
22497
|
+
}),
|
|
22498
|
+
prompt.confirming && /* @__PURE__ */ jsx(DismissPrompt, { choices: "Dismiss this request? d: decline c: cancel any other key: back" }),
|
|
22499
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22500
|
+
flexGrow: 1,
|
|
22501
|
+
width: "100%",
|
|
22502
|
+
children: /* @__PURE__ */ jsx(Form, {
|
|
22503
|
+
form,
|
|
22504
|
+
customManagers: FORM_FIELD_MANAGERS,
|
|
22505
|
+
onSubmit: (values) => handleSubmit(values)
|
|
22506
|
+
})
|
|
22507
|
+
})
|
|
22508
|
+
]
|
|
22509
|
+
});
|
|
22510
|
+
}
|
|
22511
|
+
function ElicitationUrlRequest({ elicitation, message, url, inspectorClient, queueLabel, width, height }) {
|
|
22512
|
+
const [status, setStatus] = useState(null);
|
|
22513
|
+
const settleWith = useSettle(setStatus);
|
|
22514
|
+
const refusal = elicitationUrlRefusal(url);
|
|
22515
|
+
const messageRef = useRef(null);
|
|
22516
|
+
const settle = (result) => settleWith(() => settleElicitation(elicitation, result, inspectorClient));
|
|
22517
|
+
useInput((input, key) => {
|
|
22518
|
+
if (input === "o") {
|
|
22519
|
+
if (refusal) {
|
|
22520
|
+
setStatus(refusal);
|
|
22521
|
+
return;
|
|
22522
|
+
}
|
|
22523
|
+
openUrl(url, setStatus);
|
|
22524
|
+
} else if (key.return) settle({ action: "accept" });
|
|
22525
|
+
else if (input === "d") settle({ action: "decline" });
|
|
22526
|
+
else if (key.escape || input === "c") settle({ action: "cancel" });
|
|
22527
|
+
else if (key.pageDown) messageRef.current?.scrollBy(1);
|
|
22528
|
+
else if (key.pageUp) messageRef.current?.scrollBy(-1);
|
|
22529
|
+
});
|
|
22530
|
+
return /* @__PURE__ */ jsxs(ModalFrame, {
|
|
22531
|
+
title: "Elicitation request (URL)",
|
|
22532
|
+
hint: "(o: open in browser, Enter: done, d: decline, ESC: cancel, PgUp/PgDn: scroll)",
|
|
22533
|
+
queueLabel,
|
|
22534
|
+
note: originNote(elicitation.origin, elicitation.taskId),
|
|
22535
|
+
status,
|
|
22536
|
+
width,
|
|
22537
|
+
height,
|
|
22538
|
+
children: [
|
|
22539
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22540
|
+
flexShrink: 0,
|
|
22541
|
+
marginBottom: 1,
|
|
22542
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22543
|
+
color: "cyan",
|
|
22544
|
+
children: url
|
|
22545
|
+
})
|
|
22546
|
+
}),
|
|
22547
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22548
|
+
height: messageBoxHeight(message, width - 6, height),
|
|
22549
|
+
flexShrink: 0,
|
|
22550
|
+
flexDirection: "column",
|
|
22551
|
+
overflow: "hidden",
|
|
22552
|
+
children: /* @__PURE__ */ jsx(ScrollView, {
|
|
22553
|
+
ref: messageRef,
|
|
22554
|
+
children: /* @__PURE__ */ jsx(Text, { children: message })
|
|
22555
|
+
})
|
|
22556
|
+
}),
|
|
22557
|
+
/* @__PURE__ */ jsx(Box, {
|
|
22558
|
+
flexShrink: 0,
|
|
22559
|
+
marginTop: 1,
|
|
22560
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
22561
|
+
dimColor: true,
|
|
22562
|
+
children: "Complete the flow in your browser, then press Enter. The Inspector cannot observe the external flow finishing."
|
|
22563
|
+
})
|
|
22564
|
+
})
|
|
22565
|
+
]
|
|
22566
|
+
});
|
|
22567
|
+
}
|
|
22568
|
+
function PendingRequestModal({ pendingSamples, pendingElicitations, inspectorClient, width, height }) {
|
|
22569
|
+
const total = pendingSamples.length + pendingElicitations.length;
|
|
22570
|
+
const queueLabel = total > 1 ? `${total} pending` : "";
|
|
22571
|
+
const sample = pendingSamples[0];
|
|
22572
|
+
if (sample) return /* @__PURE__ */ jsx(SamplingRequest, {
|
|
22573
|
+
sample,
|
|
22574
|
+
queueLabel,
|
|
22575
|
+
width,
|
|
22576
|
+
height
|
|
22577
|
+
}, sample.id);
|
|
22578
|
+
const elicitation = pendingElicitations[0];
|
|
22579
|
+
if (!elicitation) return null;
|
|
22580
|
+
const params = elicitation.request.params;
|
|
22581
|
+
if (params.mode === "url") return /* @__PURE__ */ jsx(ElicitationUrlRequest, {
|
|
22582
|
+
elicitation,
|
|
22583
|
+
message: params.message,
|
|
22584
|
+
url: params.url,
|
|
22585
|
+
inspectorClient,
|
|
22586
|
+
queueLabel,
|
|
22587
|
+
width,
|
|
22588
|
+
height
|
|
22589
|
+
}, elicitation.id);
|
|
22590
|
+
return /* @__PURE__ */ jsx(ElicitationFormRequest, {
|
|
22591
|
+
elicitation,
|
|
22592
|
+
params,
|
|
22593
|
+
inspectorClient,
|
|
22594
|
+
queueLabel,
|
|
22595
|
+
width,
|
|
22596
|
+
height
|
|
22597
|
+
}, elicitation.id);
|
|
22598
|
+
}
|
|
22599
|
+
// src/App.tsx
|
|
21796
22600
|
const APP_NAME = "MCP Inspector TUI";
|
|
21797
22601
|
const APP_DESCRIPTION = "Terminal User Interface for the Model Context Protocol Inspector";
|
|
21798
22602
|
const APP_VERSION = readInspectorVersion(import.meta.url);
|
|
@@ -21809,7 +22613,6 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21809
22613
|
const [activeTab, setActiveTab] = useState("info");
|
|
21810
22614
|
const [paneFocus, setFocus] = useState("serverList");
|
|
21811
22615
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
21812
|
-
const focus = helpOpen ? "help" : paneFocus;
|
|
21813
22616
|
const [listFilterEditing, setListFilterEditing] = useState(false);
|
|
21814
22617
|
const [listFilterClaimsEscape, setListFilterClaimsEscape] = useState(false);
|
|
21815
22618
|
const [tabCounts, setTabCounts] = useState({});
|
|
@@ -21912,6 +22715,11 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
21912
22715
|
...defaultMetadata && Object.keys(defaultMetadata).length > 0 && { defaultMetadata },
|
|
21913
22716
|
...savedSettings && { serverSettings: savedSettings },
|
|
21914
22717
|
roots: cleanRoots(savedSettings?.roots ?? []),
|
|
22718
|
+
sample: true,
|
|
22719
|
+
elicit: {
|
|
22720
|
+
form: true,
|
|
22721
|
+
url: true
|
|
22722
|
+
},
|
|
21915
22723
|
...savedSettings?.protocolEra && { versionNegotiation: eraToVersionNegotiation(savedSettings.protocolEra) },
|
|
21916
22724
|
...clientAuthOptions
|
|
21917
22725
|
};
|
|
@@ -22067,6 +22875,9 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22067
22875
|
if (activeTab === "auth" && selectedServerConfig && !isOAuthCapableServerConfig(selectedServerConfig)) setActiveTab("info");
|
|
22068
22876
|
}, [activeTab, selectedServerConfig]);
|
|
22069
22877
|
const selectedInspectorClient = useMemo(() => selectedServer ? inspectorClients[selectedServer] : null, [selectedServer, inspectorClients]);
|
|
22878
|
+
const { pendingSamples, pendingElicitations } = usePendingClientRequests(selectedInspectorClient);
|
|
22879
|
+
const pendingRequestOpen = pendingSamples.length + pendingElicitations.length > 0;
|
|
22880
|
+
const focus = helpOpen || pendingRequestOpen ? "overlay" : paneFocus;
|
|
22070
22881
|
const { status: inspectorStatus, capabilities: inspectorCapabilities, serverInfo: inspectorServerInfo, instructions: inspectorInstructions, connect: connectInspector, disconnect: disconnectInspector, lastError: inspectorLastError } = useInspectorClient(selectedInspectorClient);
|
|
22071
22882
|
const selectedMessageLogState = useMemo(() => selectedServer && messageLogStates[selectedServer] ? messageLogStates[selectedServer] : null, [selectedServer, messageLogStates]);
|
|
22072
22883
|
const selectedFetchRequestLogState = useMemo(() => selectedServer && fetchRequestLogStates[selectedServer] ? fetchRequestLogStates[selectedServer] : null, [selectedServer, fetchRequestLogStates]);
|
|
@@ -22776,7 +23587,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
22776
23587
|
inspectorClients
|
|
22777
23588
|
]);
|
|
22778
23589
|
useInput((input, key) => {
|
|
22779
|
-
if (toolTestModal || resourceTestModal || promptTestModal || detailsModal || helpOpen || rootsModalOpen) return;
|
|
23590
|
+
if (toolTestModal || resourceTestModal || promptTestModal || detailsModal || helpOpen || rootsModalOpen || pendingRequestOpen) return;
|
|
22780
23591
|
if (key.ctrl && input === "c") exit();
|
|
22781
23592
|
if (listFilterEditing) return;
|
|
22782
23593
|
if (input === "?") {
|
|
@@ -23403,6 +24214,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
23403
24214
|
width: dimensions.width,
|
|
23404
24215
|
height: dimensions.height,
|
|
23405
24216
|
onClose: () => setToolTestModal(null),
|
|
24217
|
+
inputActive: !pendingRequestOpen,
|
|
23406
24218
|
onAuthRecoveryRequired: (error) => {
|
|
23407
24219
|
onAuthRecoveryRequired(error);
|
|
23408
24220
|
setToolTestModal(null);
|
|
@@ -23414,6 +24226,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
23414
24226
|
width: dimensions.width,
|
|
23415
24227
|
height: dimensions.height,
|
|
23416
24228
|
onClose: () => setResourceTestModal(null),
|
|
24229
|
+
inputActive: !pendingRequestOpen,
|
|
23417
24230
|
onAuthRecoveryRequired: (error) => {
|
|
23418
24231
|
onAuthRecoveryRequired(error);
|
|
23419
24232
|
setResourceTestModal(null);
|
|
@@ -23425,6 +24238,7 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
23425
24238
|
width: dimensions.width,
|
|
23426
24239
|
height: dimensions.height,
|
|
23427
24240
|
onClose: () => setPromptTestModal(null),
|
|
24241
|
+
inputActive: !pendingRequestOpen,
|
|
23428
24242
|
onAuthRecoveryRequired: (error) => {
|
|
23429
24243
|
onAuthRecoveryRequired(error);
|
|
23430
24244
|
setPromptTestModal(null);
|
|
@@ -23434,7 +24248,8 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
23434
24248
|
sections: keybindingSections(activeTab, shownTabs),
|
|
23435
24249
|
width: dimensions.width,
|
|
23436
24250
|
height: dimensions.height,
|
|
23437
|
-
onClose: () => setHelpOpen(false)
|
|
24251
|
+
onClose: () => setHelpOpen(false),
|
|
24252
|
+
inputActive: !pendingRequestOpen
|
|
23438
24253
|
}),
|
|
23439
24254
|
rootsModalOpen && /* @__PURE__ */ jsx(RootsModal, {
|
|
23440
24255
|
roots: advertisedRoots,
|
|
@@ -23442,7 +24257,8 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
23442
24257
|
connected: inspectorStatus === "connected",
|
|
23443
24258
|
width: dimensions.width,
|
|
23444
24259
|
height: dimensions.height,
|
|
23445
|
-
onClose: () => setRootsModalOpen(false)
|
|
24260
|
+
onClose: () => setRootsModalOpen(false),
|
|
24261
|
+
inputActive: !pendingRequestOpen
|
|
23446
24262
|
}),
|
|
23447
24263
|
detailsModal && !helpOpen && /* @__PURE__ */ jsx(DetailsModal, {
|
|
23448
24264
|
title: detailsModal.title,
|
|
@@ -23450,13 +24266,20 @@ function App({ mcpServers, clientConfig, clientId, clientSecret, clientMetadataU
|
|
|
23450
24266
|
width: dimensions.width,
|
|
23451
24267
|
height: dimensions.height,
|
|
23452
24268
|
onClose: () => setDetailsModal(null),
|
|
23453
|
-
copyText: detailsModal.copyText
|
|
24269
|
+
copyText: detailsModal.copyText,
|
|
24270
|
+
inputActive: !pendingRequestOpen
|
|
24271
|
+
}),
|
|
24272
|
+
/* @__PURE__ */ jsx(PendingRequestModal, {
|
|
24273
|
+
pendingSamples,
|
|
24274
|
+
pendingElicitations,
|
|
24275
|
+
inspectorClient: selectedInspectorClient,
|
|
24276
|
+
width: dimensions.width,
|
|
24277
|
+
height: dimensions.height
|
|
23454
24278
|
})
|
|
23455
24279
|
]
|
|
23456
24280
|
});
|
|
23457
24281
|
}
|
|
23458
|
-
|
|
23459
|
-
//#region tui.tsx
|
|
24282
|
+
// tui.tsx
|
|
23460
24283
|
async function runTui(args) {
|
|
23461
24284
|
const program = new Command();
|
|
23462
24285
|
program.name("mcp-inspector-tui").description("Terminal UI for MCP Inspector").version(readInspectorVersion(import.meta.url), "-V, --version", "Print the Inspector version").option("--catalog <path>", "Writable catalog file (created if missing; default: ~/.mcp-inspector/mcp.json, or MCP_CATALOG_PATH)").option("--config <path>", "Read-only session config file (served as-is, never written or seeded; errors if absent)").option("-e <key=value...>", "Environment variables for stdio servers", parseKeyValuePair, {}).option("--cwd <path>", "Working directory for stdio servers").option("--header <header...>", "HTTP headers as \"Name: Value\"", parseHeaderPair, {}).option("--protocol-era <era>", "Protocol era to negotiate: legacy, auto, or modern (overrides the file's protocolEra; default legacy)", parseProtocolEra).option("--skill-catalog-max-skills <n>", "Skills catalog budget: the most skills one multi-skill verification run reads (positive integer; overrides the file's skillCatalogMaxSkills; default 256). Bounds the Skills pane's v (verify all); Enter verifies one skill in full", skillCatalogLimitParser("--skill-catalog-max-skills")).option("--skill-catalog-max-bytes <n>", "Skills catalog budget: the most bytes one multi-skill verification run reads (positive integer; overrides the file's skillCatalogMaxBytes; default 64 MiB). Bounds the Skills pane's v (verify all); Enter verifies one skill in full", skillCatalogLimitParser("--skill-catalog-max-bytes")).option("--client-id <id>", "OAuth client ID (static client) for HTTP servers").option("--client-secret <secret>", "OAuth client secret (for confidential clients)").option("--client-metadata-url <url>", "OAuth Client ID Metadata Document URL (CIMD) for HTTP servers").option("--client-config <path>", "Install-level client config (default: ~/.mcp-inspector/storage/client.json, or MCP_CLIENT_CONFIG_PATH)").option("--callback-url <url>", `OAuth redirect/callback listener URL; must be loopback (default: ${DEFAULT_RUNNER_OAUTH_CALLBACK_URL}, or MCP_OAUTH_CALLBACK_URL)`).argument("[target...]", "Command and args or URL for a single ad-hoc server (when not using --config)").option("--transport <type>", "Transport: stdio, sse, or http (ad-hoc only)").option("--server-url <url>", "Server URL (ad-hoc only)").parse(args ?? process.argv);
|
|
@@ -23511,8 +24334,7 @@ async function runTui(args) {
|
|
|
23511
24334
|
process.exit(1);
|
|
23512
24335
|
}
|
|
23513
24336
|
}
|
|
23514
|
-
|
|
23515
|
-
//#region index.ts
|
|
24337
|
+
// index.ts
|
|
23516
24338
|
const __filename = fileURLToPath(import.meta.url);
|
|
23517
24339
|
if (process.argv[1] !== void 0 && resolve(process.argv[1]) === resolve(__filename)) runTui(process.argv).catch((err) => {
|
|
23518
24340
|
console.error("Error:", err instanceof Error ? err.message : err);
|
|
@@ -23523,5 +24345,4 @@ if (process.argv[1] !== void 0 && resolve(process.argv[1]) === resolve(__filenam
|
|
|
23523
24345
|
if ((debugOn(process.env.MCP_DEBUG) || debugOn(process.env.DEBUG)) && err instanceof Error) console.error(err.stack);
|
|
23524
24346
|
process.exit(1);
|
|
23525
24347
|
});
|
|
23526
|
-
//#endregion
|
|
23527
24348
|
export { runTui };
|