@modelcontextprotocol/inspector 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/clients/cli/build/index.js +1565 -329
- package/clients/tui/build/index.js +1651 -576
- package/clients/web/build/index.js +2481 -1216
- package/clients/web/dist/assets/index-DgXruQhz.js +1598 -0
- package/clients/web/dist/assets/{prism-light-CGBvpchP.js → prism-light-leP1dqtE.js} +1 -1
- package/clients/web/dist/index.html +1 -1
- package/package.json +9 -7
- package/clients/web/dist/assets/index-9ZWu1ACP.js +0 -1598
|
@@ -165,6 +165,10 @@ var ModernListSkillsResultSchema = ListSkillsResultSchema.extend({
|
|
|
165
165
|
var GetSkillEnvelopeSchema = z.looseObject({
|
|
166
166
|
skill: SkillEntrySchema
|
|
167
167
|
});
|
|
168
|
+
var ModernGetSkillEnvelopeSchema = GetSkillEnvelopeSchema.extend({
|
|
169
|
+
ttlMs: z.int().min(0),
|
|
170
|
+
cacheScope: z.enum(["public", "private"])
|
|
171
|
+
});
|
|
168
172
|
var GetSkillResultSchema = GetSkillEnvelopeSchema.transform(
|
|
169
173
|
(result) => result.skill
|
|
170
174
|
);
|
|
@@ -2208,6 +2212,19 @@ import { readFileSync as readFileSync2, statSync as statSync2 } from "fs";
|
|
|
2208
2212
|
import * as fs3 from "fs/promises";
|
|
2209
2213
|
import * as path3 from "path";
|
|
2210
2214
|
|
|
2215
|
+
// ../../core/storage/own-entry.ts
|
|
2216
|
+
function setOwnEntry(map, key, value) {
|
|
2217
|
+
Object.defineProperty(map, key, {
|
|
2218
|
+
value,
|
|
2219
|
+
enumerable: true,
|
|
2220
|
+
writable: true,
|
|
2221
|
+
configurable: true
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2224
|
+
function getOwnEntry(map, key) {
|
|
2225
|
+
return map !== void 0 && Object.hasOwn(map, key) ? map[key] : void 0;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2211
2228
|
// ../../core/auth/node/file-lock.ts
|
|
2212
2229
|
import nodeFs, { statSync, rmdirSync } from "fs";
|
|
2213
2230
|
import * as fs2 from "fs/promises";
|
|
@@ -2266,6 +2283,12 @@ var SecretStoreUnavailableError = class extends Error {
|
|
|
2266
2283
|
this.name = "SecretStoreUnavailableError";
|
|
2267
2284
|
}
|
|
2268
2285
|
};
|
|
2286
|
+
var SecretFileLockHeldError = class extends SecretStoreUnavailableError {
|
|
2287
|
+
constructor(message, options) {
|
|
2288
|
+
super(message, options);
|
|
2289
|
+
this.name = "SecretFileLockHeldError";
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2269
2292
|
var KeychainUnavailableError = class extends SecretStoreUnavailableError {
|
|
2270
2293
|
constructor(cause) {
|
|
2271
2294
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -2296,6 +2319,7 @@ async function probeKeyringAvailable() {
|
|
|
2296
2319
|
try {
|
|
2297
2320
|
const entry = new keyring.mod.AsyncEntry(SERVICE_NAME, PROBE_ACCOUNT);
|
|
2298
2321
|
await entry.getPassword();
|
|
2322
|
+
await keyring.mod.findCredentialsAsync(SERVICE_NAME);
|
|
2299
2323
|
return { available: true };
|
|
2300
2324
|
} catch (err) {
|
|
2301
2325
|
return {
|
|
@@ -2305,6 +2329,7 @@ async function probeKeyringAvailable() {
|
|
|
2305
2329
|
}
|
|
2306
2330
|
}
|
|
2307
2331
|
var PROBE_ACCOUNT = "__inspector:probe";
|
|
2332
|
+
var isNoEntryError = (err) => err instanceof Error && /no (matching )?entry/i.test(err.message);
|
|
2308
2333
|
var KeyringSecretStore = class {
|
|
2309
2334
|
/**
|
|
2310
2335
|
* The intolerant read. Same lookup as {@link get}, minus the catch — a
|
|
@@ -2356,23 +2381,27 @@ var KeyringSecretStore = class {
|
|
|
2356
2381
|
async delete(serverId, field) {
|
|
2357
2382
|
try {
|
|
2358
2383
|
const keyring = await loadKeyring();
|
|
2359
|
-
if (!keyring.ok)
|
|
2384
|
+
if (!keyring.ok) throw new KeychainUnavailableError(keyring.err);
|
|
2360
2385
|
const entry = new keyring.mod.AsyncEntry(
|
|
2361
2386
|
SERVICE_NAME,
|
|
2362
2387
|
buildAccount(serverId, field)
|
|
2363
2388
|
);
|
|
2364
2389
|
await entry.deleteCredential();
|
|
2365
|
-
} catch {
|
|
2390
|
+
} catch (err) {
|
|
2391
|
+
if (isNoEntryError(err)) return;
|
|
2392
|
+
if (err instanceof KeychainUnavailableError) throw err;
|
|
2393
|
+
throw new KeychainUnavailableError(err);
|
|
2366
2394
|
}
|
|
2367
2395
|
}
|
|
2368
2396
|
async deleteAllForServer(serverId) {
|
|
2369
2397
|
let creds;
|
|
2370
2398
|
try {
|
|
2371
2399
|
const keyring = await loadKeyring();
|
|
2372
|
-
if (!keyring.ok)
|
|
2400
|
+
if (!keyring.ok) throw new KeychainUnavailableError(keyring.err);
|
|
2373
2401
|
creds = await keyring.mod.findCredentialsAsync(SERVICE_NAME);
|
|
2374
|
-
} catch {
|
|
2375
|
-
|
|
2402
|
+
} catch (err) {
|
|
2403
|
+
if (err instanceof KeychainUnavailableError) throw err;
|
|
2404
|
+
throw new KeychainUnavailableError(err);
|
|
2376
2405
|
}
|
|
2377
2406
|
const prefix = `${serverId}:`;
|
|
2378
2407
|
for (const c of creds) {
|
|
@@ -2386,6 +2415,25 @@ var KeyringSecretStore = class {
|
|
|
2386
2415
|
async function secretStoreGetStrict(store, serverId, field) {
|
|
2387
2416
|
return store.getStrict ? store.getStrict(serverId, field) : store.get(serverId, field);
|
|
2388
2417
|
}
|
|
2418
|
+
async function snapshotSecretFields(store, serverId, fields) {
|
|
2419
|
+
return Promise.all(
|
|
2420
|
+
fields.map(async (field) => ({
|
|
2421
|
+
serverId,
|
|
2422
|
+
field,
|
|
2423
|
+
value: await secretStoreGetStrict(store, serverId, field)
|
|
2424
|
+
}))
|
|
2425
|
+
);
|
|
2426
|
+
}
|
|
2427
|
+
async function restoreSecretFields(store, snapshot, onRestoreFailure) {
|
|
2428
|
+
for (const { serverId, field, value } of snapshot) {
|
|
2429
|
+
try {
|
|
2430
|
+
if (value === null) await store.delete(serverId, field);
|
|
2431
|
+
else await store.set(serverId, field, value);
|
|
2432
|
+
} catch (error) {
|
|
2433
|
+
onRestoreFailure(error);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2389
2437
|
async function secretStoreGetMany(store, requests) {
|
|
2390
2438
|
if (store.getMany) return store.getMany(requests);
|
|
2391
2439
|
const out = {};
|
|
@@ -2398,16 +2446,44 @@ async function secretStoreGetMany(store, requests) {
|
|
|
2398
2446
|
);
|
|
2399
2447
|
const found = {};
|
|
2400
2448
|
for (const [field, value] of entries) {
|
|
2401
|
-
if (value !== null) found
|
|
2449
|
+
if (value !== null) setOwnEntry(found, field, value);
|
|
2450
|
+
}
|
|
2451
|
+
setOwnEntry(out, serverId, found);
|
|
2452
|
+
})
|
|
2453
|
+
);
|
|
2454
|
+
return out;
|
|
2455
|
+
}
|
|
2456
|
+
async function secretStoreGetManyStrict(store, requests) {
|
|
2457
|
+
if (store.getManyStrict) return store.getManyStrict(requests);
|
|
2458
|
+
const out = {};
|
|
2459
|
+
await Promise.all(
|
|
2460
|
+
requests.map(async ({ serverId, fields }) => {
|
|
2461
|
+
const entries = await Promise.all(
|
|
2462
|
+
fields.map(
|
|
2463
|
+
async (field) => [
|
|
2464
|
+
field,
|
|
2465
|
+
await secretStoreGetStrict(store, serverId, field)
|
|
2466
|
+
]
|
|
2467
|
+
)
|
|
2468
|
+
);
|
|
2469
|
+
const found = {};
|
|
2470
|
+
for (const [field, value] of entries) {
|
|
2471
|
+
if (value !== null) setOwnEntry(found, field, value);
|
|
2402
2472
|
}
|
|
2403
|
-
out
|
|
2473
|
+
setOwnEntry(out, serverId, found);
|
|
2404
2474
|
})
|
|
2405
2475
|
);
|
|
2406
2476
|
return out;
|
|
2407
2477
|
}
|
|
2478
|
+
async function settleStoreMutations(mutations) {
|
|
2479
|
+
const results = await Promise.allSettled(mutations);
|
|
2480
|
+
for (const result of results) {
|
|
2481
|
+
if (result.status === "rejected") throw result.reason;
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2408
2484
|
async function secretStoreSetMany(store, serverId, values) {
|
|
2409
2485
|
if (store.setMany) return store.setMany(serverId, values);
|
|
2410
|
-
await
|
|
2486
|
+
await settleStoreMutations(
|
|
2411
2487
|
Object.entries(values).map(
|
|
2412
2488
|
([field, value]) => store.set(serverId, field, value)
|
|
2413
2489
|
)
|
|
@@ -2576,7 +2652,7 @@ async function openSecretFileLock(filePath) {
|
|
|
2576
2652
|
});
|
|
2577
2653
|
} catch (err) {
|
|
2578
2654
|
if (isStuckOrHeld(err, lockPathOf(target))) {
|
|
2579
|
-
throw new
|
|
2655
|
+
throw new SecretFileLockHeldError(
|
|
2580
2656
|
`Could not save to the secrets file at ${target}: its lock (${lockPathOf(target)}) was still held after the ${Math.round(RETRY_BUDGET_MS / 1e3)} seconds this save waited. Its secrets are intact; the value you just entered was not saved. If no other Inspector is running, remove that lock and try again.`
|
|
2581
2657
|
);
|
|
2582
2658
|
}
|
|
@@ -2685,6 +2761,13 @@ function resolveSecretPassphrase(env2 = process.env, secretFilePath) {
|
|
|
2685
2761
|
return { passphrase };
|
|
2686
2762
|
}
|
|
2687
2763
|
var buildAccount2 = (serverId, field) => `${serverId}:${field}`;
|
|
2764
|
+
function assertSecretString(field, value) {
|
|
2765
|
+
if (typeof value !== "string") {
|
|
2766
|
+
throw new TypeError(
|
|
2767
|
+
`Refusing to store a non-string secret value (${typeof value}) for "${field}": the secrets file holds only strings, and writing this would make the whole file unreadable.`
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2688
2771
|
function asSecretMap(value, filePath) {
|
|
2689
2772
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2690
2773
|
throw new SecretStoreUnavailableError(
|
|
@@ -2943,7 +3026,9 @@ var FileSecretStore = class {
|
|
|
2943
3026
|
let plain;
|
|
2944
3027
|
try {
|
|
2945
3028
|
const key = await this.deriveKey(parsed.kdf);
|
|
2946
|
-
const decipher = crypto2.createDecipheriv(CIPHER, key, parts.iv
|
|
3029
|
+
const decipher = crypto2.createDecipheriv(CIPHER, key, parts.iv, {
|
|
3030
|
+
authTagLength: GCM_TAG_BYTES
|
|
3031
|
+
});
|
|
2947
3032
|
decipher.setAuthTag(parts.tag);
|
|
2948
3033
|
plain = Buffer.concat([
|
|
2949
3034
|
decipher.update(parts.body),
|
|
@@ -2977,7 +3062,9 @@ var FileSecretStore = class {
|
|
|
2977
3062
|
};
|
|
2978
3063
|
const key = await this.deriveKey(kdf);
|
|
2979
3064
|
const iv = crypto2.randomBytes(IV_BYTES);
|
|
2980
|
-
const cipher = crypto2.createCipheriv(CIPHER, key, iv
|
|
3065
|
+
const cipher = crypto2.createCipheriv(CIPHER, key, iv, {
|
|
3066
|
+
authTagLength: GCM_TAG_BYTES
|
|
3067
|
+
});
|
|
2981
3068
|
const body = Buffer.concat([
|
|
2982
3069
|
cipher.update(JSON.stringify(map), "utf-8"),
|
|
2983
3070
|
cipher.final()
|
|
@@ -3142,9 +3229,36 @@ var FileSecretStore = class {
|
|
|
3142
3229
|
const found = {};
|
|
3143
3230
|
for (const field of fields) {
|
|
3144
3231
|
const value = map?.[buildAccount2(serverId, field)];
|
|
3145
|
-
if (value !== void 0) found
|
|
3232
|
+
if (value !== void 0) setOwnEntry(found, field, value);
|
|
3233
|
+
}
|
|
3234
|
+
setOwnEntry(out, serverId, found);
|
|
3235
|
+
}
|
|
3236
|
+
return out;
|
|
3237
|
+
}
|
|
3238
|
+
/**
|
|
3239
|
+
* Bulk twin of {@link getStrict}: the same single-pass read as
|
|
3240
|
+
* {@link getMany}, but an unreadable store throws (with the typed advice
|
|
3241
|
+
* {@link getStrict} attaches) instead of yielding no fields — required by
|
|
3242
|
+
* OAuth read hydration, whose result later drives store deletions.
|
|
3243
|
+
*/
|
|
3244
|
+
async getManyStrict(requests) {
|
|
3245
|
+
let map;
|
|
3246
|
+
try {
|
|
3247
|
+
map = await this.serialize(() => this.readMap());
|
|
3248
|
+
} catch (err) {
|
|
3249
|
+
if (err instanceof SecretStoreUnavailableError) throw err;
|
|
3250
|
+
throw new SecretStoreUnavailableError(
|
|
3251
|
+
`Could not read the secrets file at ${this.filePath}: ${err instanceof Error ? err.message : String(err)}`
|
|
3252
|
+
);
|
|
3253
|
+
}
|
|
3254
|
+
const out = {};
|
|
3255
|
+
for (const { serverId, fields } of requests) {
|
|
3256
|
+
const found = {};
|
|
3257
|
+
for (const field of fields) {
|
|
3258
|
+
const value = map?.[buildAccount2(serverId, field)];
|
|
3259
|
+
if (value !== void 0) setOwnEntry(found, field, value);
|
|
3146
3260
|
}
|
|
3147
|
-
out
|
|
3261
|
+
setOwnEntry(out, serverId, found);
|
|
3148
3262
|
}
|
|
3149
3263
|
return out;
|
|
3150
3264
|
}
|
|
@@ -3188,6 +3302,9 @@ var FileSecretStore = class {
|
|
|
3188
3302
|
*/
|
|
3189
3303
|
async setMany(serverId, values) {
|
|
3190
3304
|
if (Object.keys(values).length === 0) return;
|
|
3305
|
+
for (const [field, value] of Object.entries(values)) {
|
|
3306
|
+
assertSecretString(field, value);
|
|
3307
|
+
}
|
|
3191
3308
|
await this.serialize(
|
|
3192
3309
|
() => this.mutate((map) => {
|
|
3193
3310
|
const next = { ...map };
|
|
@@ -3199,6 +3316,7 @@ var FileSecretStore = class {
|
|
|
3199
3316
|
);
|
|
3200
3317
|
}
|
|
3201
3318
|
async set(serverId, field, value) {
|
|
3319
|
+
assertSecretString(field, value);
|
|
3202
3320
|
await this.serialize(
|
|
3203
3321
|
() => this.mutate((map) => ({
|
|
3204
3322
|
...map,
|
|
@@ -3214,9 +3332,11 @@ var FileSecretStore = class {
|
|
|
3214
3332
|
await this.deleteWhere((key) => key.startsWith(prefix));
|
|
3215
3333
|
}
|
|
3216
3334
|
/**
|
|
3217
|
-
* Shared delete body.
|
|
3218
|
-
*
|
|
3219
|
-
*
|
|
3335
|
+
* Shared delete body. Same confirmed-delete contract as the keyring
|
|
3336
|
+
* store: a deletion that cannot be confirmed (unreadable file, failed
|
|
3337
|
+
* decrypt, failed write) must escape, because reporting success would
|
|
3338
|
+
* let a caller commit state that assumes the entry is gone — once the
|
|
3339
|
+
* file becomes readable again, a later read would resurrect it.
|
|
3220
3340
|
*/
|
|
3221
3341
|
async deleteWhere(match) {
|
|
3222
3342
|
try {
|
|
@@ -3229,7 +3349,12 @@ var FileSecretStore = class {
|
|
|
3229
3349
|
return next;
|
|
3230
3350
|
})
|
|
3231
3351
|
);
|
|
3232
|
-
} catch {
|
|
3352
|
+
} catch (err) {
|
|
3353
|
+
if (err instanceof SecretStoreUnavailableError) throw err;
|
|
3354
|
+
throw new SecretStoreUnavailableError(
|
|
3355
|
+
`Could not delete from the secrets file: ${err instanceof Error ? err.message : String(err)}`,
|
|
3356
|
+
{ cause: err }
|
|
3357
|
+
);
|
|
3233
3358
|
}
|
|
3234
3359
|
}
|
|
3235
3360
|
};
|
|
@@ -3605,6 +3730,9 @@ var DeferredSecretStore = class {
|
|
|
3605
3730
|
async getMany(requests) {
|
|
3606
3731
|
return secretStoreGetMany(await this.target(), requests);
|
|
3607
3732
|
}
|
|
3733
|
+
async getManyStrict(requests) {
|
|
3734
|
+
return secretStoreGetManyStrict(await this.target(), requests);
|
|
3735
|
+
}
|
|
3608
3736
|
async get(serverId, field) {
|
|
3609
3737
|
return (await this.target()).get(serverId, field);
|
|
3610
3738
|
}
|
|
@@ -3822,12 +3950,31 @@ function redactJsonValue(value) {
|
|
|
3822
3950
|
}
|
|
3823
3951
|
return value;
|
|
3824
3952
|
}
|
|
3953
|
+
function joinSensitiveContinuations(body) {
|
|
3954
|
+
const out = [];
|
|
3955
|
+
let sensitiveAt = -1;
|
|
3956
|
+
for (const pair of body.split("&")) {
|
|
3957
|
+
const eq = pair.indexOf("=");
|
|
3958
|
+
if (eq === -1) {
|
|
3959
|
+
if (sensitiveAt !== -1 && pair.length > 0) {
|
|
3960
|
+
out[sensitiveAt] += `%26${pair}`;
|
|
3961
|
+
} else {
|
|
3962
|
+
out.push(pair);
|
|
3963
|
+
}
|
|
3964
|
+
continue;
|
|
3965
|
+
}
|
|
3966
|
+
const [key] = new URLSearchParams(pair).keys();
|
|
3967
|
+
sensitiveAt = isSensitiveField(key) && eq < pair.length - 1 ? out.length : -1;
|
|
3968
|
+
out.push(pair);
|
|
3969
|
+
}
|
|
3970
|
+
return out.join("&");
|
|
3971
|
+
}
|
|
3825
3972
|
function redactBody(body, contentType) {
|
|
3826
3973
|
if (!body) return body;
|
|
3827
3974
|
const type = (contentType ?? "").toLowerCase();
|
|
3828
3975
|
if (type.includes("application/x-www-form-urlencoded")) {
|
|
3829
3976
|
try {
|
|
3830
|
-
const params = new URLSearchParams(body);
|
|
3977
|
+
const params = new URLSearchParams(joinSensitiveContinuations(body));
|
|
3831
3978
|
let changed = false;
|
|
3832
3979
|
for (const key of new Set(params.keys())) {
|
|
3833
3980
|
if (isSensitiveField(key)) {
|
|
@@ -4861,6 +5008,23 @@ function mergeSecretsIntoClientConfig(config, secrets) {
|
|
|
4861
5008
|
}
|
|
4862
5009
|
|
|
4863
5010
|
// ../../core/client/node-persistence.ts
|
|
5011
|
+
async function withClientConfigLock(filePath, action, body) {
|
|
5012
|
+
let entered = false;
|
|
5013
|
+
try {
|
|
5014
|
+
return await withSecretFileLock(filePath, async () => {
|
|
5015
|
+
entered = true;
|
|
5016
|
+
return body();
|
|
5017
|
+
});
|
|
5018
|
+
} catch (error) {
|
|
5019
|
+
if (!entered && error instanceof SecretFileLockHeldError) {
|
|
5020
|
+
throw new SecretFileLockHeldError(
|
|
5021
|
+
`Could not ${action} the client configuration: the file at ${filePath} is locked by another Inspector process and did not become available.`,
|
|
5022
|
+
{ cause: error }
|
|
5023
|
+
);
|
|
5024
|
+
}
|
|
5025
|
+
throw error;
|
|
5026
|
+
}
|
|
5027
|
+
}
|
|
4864
5028
|
async function readIdpSecretFromKeychain(secretStore) {
|
|
4865
5029
|
const secret = await secretStore.get(
|
|
4866
5030
|
CLIENT_KEYCHAIN_ID,
|
|
@@ -4870,29 +5034,39 @@ async function readIdpSecretFromKeychain(secretStore) {
|
|
|
4870
5034
|
return { [SECRET_FIELD_IDP_CLIENT_SECRET]: secret };
|
|
4871
5035
|
}
|
|
4872
5036
|
async function migrateClientPlaintextSecret(filePath, config, secretStore) {
|
|
4873
|
-
const { stripped, secrets } = extractSecretsFromClientConfig(config);
|
|
4874
|
-
const value = secrets[SECRET_FIELD_IDP_CLIENT_SECRET];
|
|
4875
|
-
if (!value) return config;
|
|
4876
5037
|
try {
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
5038
|
+
return await withClientConfigLock(filePath, "migrate", async () => {
|
|
5039
|
+
const raw = await readStoreFile(filePath);
|
|
5040
|
+
if (raw === null) return {};
|
|
5041
|
+
const fresh = parseClientConfig(parseStore(raw));
|
|
5042
|
+
const { stripped, secrets } = extractSecretsFromClientConfig(fresh);
|
|
5043
|
+
const value = secrets[SECRET_FIELD_IDP_CLIENT_SECRET];
|
|
5044
|
+
if (!value) return fresh;
|
|
5045
|
+
try {
|
|
5046
|
+
const existing = await secretStoreGetStrict(
|
|
5047
|
+
secretStore,
|
|
5048
|
+
CLIENT_KEYCHAIN_ID,
|
|
5049
|
+
SECRET_FIELD_IDP_CLIENT_SECRET
|
|
5050
|
+
);
|
|
5051
|
+
if (existing === null) {
|
|
5052
|
+
await secretStore.set(
|
|
5053
|
+
CLIENT_KEYCHAIN_ID,
|
|
5054
|
+
SECRET_FIELD_IDP_CLIENT_SECRET,
|
|
5055
|
+
value
|
|
5056
|
+
);
|
|
5057
|
+
}
|
|
5058
|
+
if (!await secretStoreIsDurable(secretStore)) return fresh;
|
|
5059
|
+
await writeStoreFile(filePath, serializeStore(stripped));
|
|
5060
|
+
return stripped;
|
|
5061
|
+
} catch (err) {
|
|
5062
|
+
if (err instanceof SecretStoreUnavailableError) {
|
|
5063
|
+
return fresh;
|
|
5064
|
+
}
|
|
5065
|
+
throw err;
|
|
5066
|
+
}
|
|
5067
|
+
});
|
|
4892
5068
|
} catch (err) {
|
|
4893
|
-
if (err instanceof
|
|
4894
|
-
return config;
|
|
4895
|
-
}
|
|
5069
|
+
if (err instanceof SecretFileLockHeldError) return config;
|
|
4896
5070
|
throw err;
|
|
4897
5071
|
}
|
|
4898
5072
|
}
|
|
@@ -5095,7 +5269,7 @@ import {
|
|
|
5095
5269
|
useCallback as useCallback14,
|
|
5096
5270
|
useRef as useRef15
|
|
5097
5271
|
} from "react";
|
|
5098
|
-
import { Box as
|
|
5272
|
+
import { Box as Box29, Text as Text26, useInput as useInput22, useApp } from "ink";
|
|
5099
5273
|
|
|
5100
5274
|
// ../../core/mcp/inspectorClient.ts
|
|
5101
5275
|
import { Client } from "@modelcontextprotocol/client";
|
|
@@ -5486,10 +5660,13 @@ var ADVERTISABLE_EXTENSIONS = [
|
|
|
5486
5660
|
{
|
|
5487
5661
|
key: UI_EXTENSION_KEY,
|
|
5488
5662
|
label: "MCP Apps UI (io.modelcontextprotocol/ui)",
|
|
5489
|
-
// The MCP Apps UI extension
|
|
5490
|
-
//
|
|
5491
|
-
// a
|
|
5663
|
+
// The MCP Apps UI extension, advertised with the App resource MIME type the
|
|
5664
|
+
// Inspector renders — a conforming server checks the `mimeTypes` before
|
|
5665
|
+
// serving a UI resource. Default-on only where Apps can actually be
|
|
5666
|
+
// rendered (the web client); the CLI and TUI cannot, so they leave it off
|
|
5667
|
+
// unless explicitly overridden (#2403).
|
|
5492
5668
|
defaultAdvertised: true,
|
|
5669
|
+
requiresAppRenderer: true,
|
|
5493
5670
|
advertisement: { mimeTypes: [MCP_APP_MIME_TYPE] }
|
|
5494
5671
|
},
|
|
5495
5672
|
{
|
|
@@ -5505,10 +5682,13 @@ var ADVERTISABLE_EXTENSIONS = [
|
|
|
5505
5682
|
defaultAdvertised: true
|
|
5506
5683
|
}
|
|
5507
5684
|
];
|
|
5685
|
+
function isAdvertisedByDefault(ext, rendersApps) {
|
|
5686
|
+
return ext.defaultAdvertised && (!ext.requiresAppRenderer || rendersApps);
|
|
5687
|
+
}
|
|
5508
5688
|
function buildClientExtensions(input) {
|
|
5509
5689
|
const map = {};
|
|
5510
5690
|
for (const ext of ADVERTISABLE_EXTENSIONS) {
|
|
5511
|
-
const advertised = input.advertised?.[ext.key] ?? ext.
|
|
5691
|
+
const advertised = input.advertised?.[ext.key] ?? isAdvertisedByDefault(ext, input.rendersApps === true);
|
|
5512
5692
|
if (advertised) {
|
|
5513
5693
|
map[ext.key] = ext.advertisement ? structuredClone(ext.advertisement) : {};
|
|
5514
5694
|
}
|
|
@@ -6498,6 +6678,14 @@ function exemptMcpEndpoint(getServerUrl, negotiatesEndpoint) {
|
|
|
6498
6678
|
};
|
|
6499
6679
|
}
|
|
6500
6680
|
var REQUEST_DEADLINES = /* @__PURE__ */ new WeakMap();
|
|
6681
|
+
function stampRequestDeadline(init, budget) {
|
|
6682
|
+
if (REQUEST_DEADLINES.has(init)) {
|
|
6683
|
+
throw new Error(
|
|
6684
|
+
"stampRequestDeadline: this RequestInit already carries a deadline \u2014 withOAuthRequestTimeout must build a fresh init per call (#2418)"
|
|
6685
|
+
);
|
|
6686
|
+
}
|
|
6687
|
+
REQUEST_DEADLINES.set(init, budget);
|
|
6688
|
+
}
|
|
6501
6689
|
function requestHeadersOf(input, init) {
|
|
6502
6690
|
if (init?.headers) return new Headers(init.headers);
|
|
6503
6691
|
if (typeof input !== "string" && !(input instanceof URL)) {
|
|
@@ -6555,7 +6743,7 @@ function withOAuthRequestTimeout(fetchFn, timeoutMs = DEFAULT_OAUTH_REQUEST_TIME
|
|
|
6555
6743
|
}
|
|
6556
6744
|
});
|
|
6557
6745
|
const nextInit = { ...init, signal };
|
|
6558
|
-
|
|
6746
|
+
stampRequestDeadline(nextInit, budget);
|
|
6559
6747
|
let settled;
|
|
6560
6748
|
let drainReader;
|
|
6561
6749
|
try {
|
|
@@ -7482,7 +7670,7 @@ async function collectGrants(snapshot) {
|
|
|
7482
7670
|
return { grants, failures };
|
|
7483
7671
|
}
|
|
7484
7672
|
async function parseTokens(raw) {
|
|
7485
|
-
return raw === void 0 || raw === null ? void 0 : await OAuthTokensSchema.parseAsync(raw);
|
|
7673
|
+
return raw === void 0 || raw === null ? void 0 : await OAuthTokensSchema.partial().parseAsync(raw);
|
|
7486
7674
|
}
|
|
7487
7675
|
async function parseClient(raw) {
|
|
7488
7676
|
return raw === void 0 || raw === null ? void 0 : await OAuthClientInformationSchema.parseAsync(raw);
|
|
@@ -9263,6 +9451,14 @@ function progressTokenOf(message) {
|
|
|
9263
9451
|
}
|
|
9264
9452
|
return void 0;
|
|
9265
9453
|
}
|
|
9454
|
+
function waitForProgressToken(waits, token) {
|
|
9455
|
+
const exact = waits.get(token);
|
|
9456
|
+
if (exact !== void 0 || typeof token === "number") {
|
|
9457
|
+
return exact;
|
|
9458
|
+
}
|
|
9459
|
+
const numeric = Number(token);
|
|
9460
|
+
return Number.isSafeInteger(numeric) ? waits.get(numeric) : void 0;
|
|
9461
|
+
}
|
|
9266
9462
|
|
|
9267
9463
|
// ../../core/mcp/remote/remoteClientTransport.ts
|
|
9268
9464
|
var DEFAULT_SSE_RESPONSE_TIMEOUT_MS = 6e4;
|
|
@@ -9739,8 +9935,8 @@ var RemoteClientTransport = class {
|
|
|
9739
9935
|
});
|
|
9740
9936
|
}
|
|
9741
9937
|
/** Re-arm a pending request's SSE wait timeout on a matching progress note. */
|
|
9742
|
-
resetSseResponseWait(
|
|
9743
|
-
this.sseResponseWaits
|
|
9938
|
+
resetSseResponseWait(progressToken) {
|
|
9939
|
+
waitForProgressToken(this.sseResponseWaits, progressToken)?.resetTimeout();
|
|
9744
9940
|
}
|
|
9745
9941
|
async postSend(message, options, retryCount) {
|
|
9746
9942
|
const requestId = requestIdForMessage(message);
|
|
@@ -9945,6 +10141,11 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
9945
10141
|
requestTimeout;
|
|
9946
10142
|
defaultMetadata;
|
|
9947
10143
|
serverSettings;
|
|
10144
|
+
// The settings the current transport was built from. `serverSettings` is
|
|
10145
|
+
// replaced live on every settings save (#1444), but transport-level inputs
|
|
10146
|
+
// such as custom headers are fixed when the transport is created, so this
|
|
10147
|
+
// is what the open connection actually sends (#2460).
|
|
10148
|
+
transportSettings;
|
|
9948
10149
|
versionNegotiation;
|
|
9949
10150
|
status = "disconnected";
|
|
9950
10151
|
// True only while an explicit disconnect() owns the teardown. close() can
|
|
@@ -10299,6 +10500,10 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
10299
10500
|
const advertisedExtensions = buildClientExtensions({
|
|
10300
10501
|
enterpriseManaged: options.oauth?.enterpriseManaged ?? false,
|
|
10301
10502
|
advertised: this.advertisedExtensions,
|
|
10503
|
+
// Only a client that can render Apps claims the UI extension by default
|
|
10504
|
+
// (#2403). An app-elicitation renderer is itself a claim to host an App,
|
|
10505
|
+
// so supplying one implies it.
|
|
10506
|
+
rendersApps: options.rendersApps === true || this.appElicitationRenderer !== void 0,
|
|
10302
10507
|
// Read off the built `capabilities.elicitation.form` rather than
|
|
10303
10508
|
// re-deriving from `options.elicit`: the nested MCP Apps `elicitation`
|
|
10304
10509
|
// setting must never be advertised without the core form capability it
|
|
@@ -10724,6 +10929,7 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
10724
10929
|
}
|
|
10725
10930
|
this.baseTransport = null;
|
|
10726
10931
|
this.transport = null;
|
|
10932
|
+
this.transportSettings = void 0;
|
|
10727
10933
|
this.transportHasAuthProvider = false;
|
|
10728
10934
|
}
|
|
10729
10935
|
/**
|
|
@@ -11197,6 +11403,7 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
11197
11403
|
transportOptions
|
|
11198
11404
|
);
|
|
11199
11405
|
this.baseTransport = baseTransport;
|
|
11406
|
+
this.transportSettings = transportOptions.settings;
|
|
11200
11407
|
if (this.directAuthRecovery) {
|
|
11201
11408
|
this.directAuthRecoveryActive = !(baseTransport instanceof RemoteClientTransport);
|
|
11202
11409
|
}
|
|
@@ -11398,6 +11605,7 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
11398
11605
|
}
|
|
11399
11606
|
this.baseTransport = null;
|
|
11400
11607
|
this.transport = null;
|
|
11608
|
+
this.transportSettings = void 0;
|
|
11401
11609
|
this.transportHasAuthProvider = false;
|
|
11402
11610
|
this.clearPendingPeerRequests();
|
|
11403
11611
|
if (this.status !== "disconnected") {
|
|
@@ -12130,6 +12338,13 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
12130
12338
|
getClientCapabilities() {
|
|
12131
12339
|
return this.clientCapabilities;
|
|
12132
12340
|
}
|
|
12341
|
+
/**
|
|
12342
|
+
* Get the client identity (name, version) this client reports to servers —
|
|
12343
|
+
* the caller's `clientIdentity`, or core's neutral fallback without one.
|
|
12344
|
+
*/
|
|
12345
|
+
getClientInfo() {
|
|
12346
|
+
return this.clientInfo;
|
|
12347
|
+
}
|
|
12133
12348
|
/**
|
|
12134
12349
|
* Get server info (name, version)
|
|
12135
12350
|
*/
|
|
@@ -12181,6 +12396,16 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
12181
12396
|
getServerSettings() {
|
|
12182
12397
|
return this.serverSettings;
|
|
12183
12398
|
}
|
|
12399
|
+
/**
|
|
12400
|
+
* The settings the current transport was built from, or `undefined` when no
|
|
12401
|
+
* transport exists. Unlike {@link getServerSettings}, a live settings edit
|
|
12402
|
+
* does not change this: transport-level inputs (custom headers) apply only
|
|
12403
|
+
* when the next transport is created, so comparing the two tells a caller
|
|
12404
|
+
* whether an edit is still waiting on a reconnect (#2460).
|
|
12405
|
+
*/
|
|
12406
|
+
getTransportSettings() {
|
|
12407
|
+
return this.transportSettings;
|
|
12408
|
+
}
|
|
12184
12409
|
/**
|
|
12185
12410
|
* Replace the in-memory per-server settings on a live client. Lets a settings
|
|
12186
12411
|
* edit (e.g. toggling auto-refresh-on-list-changed) take effect on the
|
|
@@ -13702,10 +13927,9 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
13702
13927
|
* removes it before the result gets here (#2373).
|
|
13703
13928
|
*
|
|
13704
13929
|
* Separate from {@link getSkill} because the callers differ: the UIs want the
|
|
13705
|
-
* entry, while the CLI prints the result and must not reshape it.
|
|
13706
|
-
*
|
|
13707
|
-
*
|
|
13708
|
-
* those (Copilot).
|
|
13930
|
+
* entry, while the CLI prints the result and must not reshape it. A modern
|
|
13931
|
+
* result carries `ttlMs` / `cacheScope` (#2404), and unwrapping to the entry
|
|
13932
|
+
* discards exactly those (Copilot).
|
|
13709
13933
|
*/
|
|
13710
13934
|
async getSkillResult(uri, metadata) {
|
|
13711
13935
|
if (!this.client) {
|
|
@@ -13716,11 +13940,12 @@ var InspectorClient = class _InspectorClient extends InspectorClientEventTarget
|
|
|
13716
13940
|
uri,
|
|
13717
13941
|
...effectiveMeta ? { _meta: effectiveMeta } : {}
|
|
13718
13942
|
};
|
|
13943
|
+
const resultSchema = this.isModernEra() ? ModernGetSkillEnvelopeSchema : GetSkillEnvelopeSchema;
|
|
13719
13944
|
try {
|
|
13720
13945
|
return await this.invokeMcpClient(
|
|
13721
13946
|
() => this.client.request(
|
|
13722
13947
|
{ method: SKILLS_GET_METHOD, params },
|
|
13723
|
-
|
|
13948
|
+
resultSchema,
|
|
13724
13949
|
this.getRequestOptions(this.progressTokenOf(metadata))
|
|
13725
13950
|
),
|
|
13726
13951
|
{ method: SKILLS_GET_METHOD }
|
|
@@ -16051,42 +16276,57 @@ import {
|
|
|
16051
16276
|
function withIssuer(value, issuer) {
|
|
16052
16277
|
return issuer === void 0 ? value : { ...value, issuer };
|
|
16053
16278
|
}
|
|
16054
|
-
var
|
|
16279
|
+
var OAuthStorageCoordination = class {
|
|
16055
16280
|
loaded = false;
|
|
16056
16281
|
loadPromise;
|
|
16057
16282
|
/** Serializes persist writes so concurrent mutators cannot reorder POSTs. */
|
|
16058
16283
|
persistQueue = Promise.resolve();
|
|
16284
|
+
};
|
|
16285
|
+
var OAuthStorageBase = class {
|
|
16286
|
+
coordination;
|
|
16059
16287
|
memory;
|
|
16060
16288
|
backend;
|
|
16061
|
-
constructor(memory, backend) {
|
|
16289
|
+
constructor(memory, backend, coordination = new OAuthStorageCoordination()) {
|
|
16062
16290
|
this.memory = memory;
|
|
16063
16291
|
this.backend = backend;
|
|
16292
|
+
this.coordination = coordination;
|
|
16064
16293
|
}
|
|
16065
16294
|
load() {
|
|
16066
|
-
|
|
16067
|
-
|
|
16295
|
+
const coordination = this.coordination;
|
|
16296
|
+
if (!coordination.loadPromise) {
|
|
16297
|
+
coordination.loadPromise = this.doLoad().catch((error) => {
|
|
16298
|
+
coordination.loadPromise = void 0;
|
|
16299
|
+
throw error;
|
|
16300
|
+
});
|
|
16068
16301
|
}
|
|
16069
|
-
return
|
|
16302
|
+
return coordination.loadPromise;
|
|
16070
16303
|
}
|
|
16071
16304
|
async doLoad() {
|
|
16072
|
-
if (this.loaded) {
|
|
16305
|
+
if (this.coordination.loaded) {
|
|
16073
16306
|
return;
|
|
16074
16307
|
}
|
|
16075
16308
|
const snapshot = await this.backend.read();
|
|
16076
16309
|
if (snapshot) {
|
|
16077
16310
|
this.memory.replace(snapshot);
|
|
16078
16311
|
}
|
|
16079
|
-
this.loaded = true;
|
|
16312
|
+
this.coordination.loaded = true;
|
|
16080
16313
|
}
|
|
16081
16314
|
async ensureLoaded() {
|
|
16082
16315
|
await this.load();
|
|
16083
16316
|
}
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16317
|
+
/**
|
|
16318
|
+
* Flush memory to the backend, naming the sections the calling mutation
|
|
16319
|
+
* touched so shared-store backends can merge just those entries over a
|
|
16320
|
+
* fresh read (the clobber fix — see {@link OAuthPersistSections}). The
|
|
16321
|
+
* snapshot is taken *inside* the queued closure, so a write that waited in
|
|
16322
|
+
* the queue carries the state as of when it actually runs, coalescing with
|
|
16323
|
+
* any mutations that landed in memory while it waited.
|
|
16324
|
+
*/
|
|
16325
|
+
async persist(sections) {
|
|
16326
|
+
const prior = this.coordination.persistQueue;
|
|
16087
16327
|
const tracked = prior.catch(() => {
|
|
16088
|
-
}).then(() => this.backend.write(snapshot));
|
|
16089
|
-
this.persistQueue = tracked;
|
|
16328
|
+
}).then(() => this.backend.write(this.memory.snapshot(), sections));
|
|
16329
|
+
this.coordination.persistQueue = tracked;
|
|
16090
16330
|
await tracked;
|
|
16091
16331
|
}
|
|
16092
16332
|
/**
|
|
@@ -16100,7 +16340,7 @@ var OAuthStorageBase = class {
|
|
|
16100
16340
|
/** Read the issuer-bound slot for a read, if one exists. */
|
|
16101
16341
|
issuerSlot(state, issuer) {
|
|
16102
16342
|
const key = this.resolveReadIssuer(state, issuer);
|
|
16103
|
-
return key ? state.byIssuer
|
|
16343
|
+
return key ? getOwnEntry(state.byIssuer, key) : void 0;
|
|
16104
16344
|
}
|
|
16105
16345
|
/**
|
|
16106
16346
|
* Read-modify-write the `byIssuer[issuer]` slot, set `activeIssuer`, and clear
|
|
@@ -16111,7 +16351,9 @@ var OAuthStorageBase = class {
|
|
|
16111
16351
|
const state = this.memory.getState().getServerState(serverUrl);
|
|
16112
16352
|
const byIssuer = {
|
|
16113
16353
|
...state.byIssuer,
|
|
16114
|
-
|
|
16354
|
+
// The computed key defines an own property; the merge-base read needs
|
|
16355
|
+
// the own guard so an absent `__proto__` slot reads as undefined.
|
|
16356
|
+
[issuer]: { ...getOwnEntry(state.byIssuer, issuer), ...updates }
|
|
16115
16357
|
};
|
|
16116
16358
|
this.memory.getState().setServerState(serverUrl, {
|
|
16117
16359
|
byIssuer,
|
|
@@ -16123,7 +16365,7 @@ var OAuthStorageBase = class {
|
|
|
16123
16365
|
mapIssuerSlots(state, fn) {
|
|
16124
16366
|
const byIssuer = {};
|
|
16125
16367
|
for (const [key, slot] of Object.entries(state.byIssuer ?? {})) {
|
|
16126
|
-
byIssuer
|
|
16368
|
+
setOwnEntry(byIssuer, key, { ...slot, ...fn(slot) });
|
|
16127
16369
|
}
|
|
16128
16370
|
return byIssuer;
|
|
16129
16371
|
}
|
|
@@ -16169,7 +16411,7 @@ var OAuthStorageBase = class {
|
|
|
16169
16411
|
clientRegistrationKind: options.registrationKind
|
|
16170
16412
|
});
|
|
16171
16413
|
}
|
|
16172
|
-
await this.persist();
|
|
16414
|
+
await this.persist({ servers: [serverUrl] });
|
|
16173
16415
|
}
|
|
16174
16416
|
async savePreregisteredClientInformation(serverUrl, clientInformation) {
|
|
16175
16417
|
await this.ensureLoaded();
|
|
@@ -16177,7 +16419,7 @@ var OAuthStorageBase = class {
|
|
|
16177
16419
|
preregisteredClientInformation: clientInformation,
|
|
16178
16420
|
clientRegistrationKind: "static"
|
|
16179
16421
|
});
|
|
16180
|
-
await this.persist();
|
|
16422
|
+
await this.persist({ servers: [serverUrl] });
|
|
16181
16423
|
}
|
|
16182
16424
|
async clearClientInformation(serverUrl, isPreregistered, issuer) {
|
|
16183
16425
|
await this.ensureLoaded();
|
|
@@ -16185,7 +16427,7 @@ var OAuthStorageBase = class {
|
|
|
16185
16427
|
this.memory.getState().setServerState(serverUrl, {
|
|
16186
16428
|
preregisteredClientInformation: void 0
|
|
16187
16429
|
});
|
|
16188
|
-
await this.persist();
|
|
16430
|
+
await this.persist({ servers: [serverUrl] });
|
|
16189
16431
|
return;
|
|
16190
16432
|
}
|
|
16191
16433
|
if (issuer !== void 0) {
|
|
@@ -16208,7 +16450,7 @@ var OAuthStorageBase = class {
|
|
|
16208
16450
|
clientRegistrationKind: void 0
|
|
16209
16451
|
});
|
|
16210
16452
|
}
|
|
16211
|
-
await this.persist();
|
|
16453
|
+
await this.persist({ servers: [serverUrl] });
|
|
16212
16454
|
}
|
|
16213
16455
|
async getTokens(serverUrl, issuer) {
|
|
16214
16456
|
await this.ensureLoaded();
|
|
@@ -16219,9 +16461,12 @@ var OAuthStorageBase = class {
|
|
|
16219
16461
|
if (!tokens) {
|
|
16220
16462
|
return void 0;
|
|
16221
16463
|
}
|
|
16222
|
-
const
|
|
16464
|
+
const result = await OAuthTokensSchema3.safeParseAsync(tokens);
|
|
16465
|
+
if (!result.success) {
|
|
16466
|
+
return void 0;
|
|
16467
|
+
}
|
|
16223
16468
|
return withIssuer(
|
|
16224
|
-
|
|
16469
|
+
result.data,
|
|
16225
16470
|
fromSlot ? this.resolveReadIssuer(state, issuer) : void 0
|
|
16226
16471
|
);
|
|
16227
16472
|
}
|
|
@@ -16245,7 +16490,7 @@ var OAuthStorageBase = class {
|
|
|
16245
16490
|
...options?.enterpriseManaged === true && { enterpriseManaged: true }
|
|
16246
16491
|
});
|
|
16247
16492
|
}
|
|
16248
|
-
await this.persist();
|
|
16493
|
+
await this.persist({ servers: [serverUrl] });
|
|
16249
16494
|
}
|
|
16250
16495
|
async clearTokens(serverUrl, issuer) {
|
|
16251
16496
|
await this.ensureLoaded();
|
|
@@ -16264,7 +16509,7 @@ var OAuthStorageBase = class {
|
|
|
16264
16509
|
}));
|
|
16265
16510
|
this.memory.getState().setServerState(serverUrl, { byIssuer, tokens: void 0 });
|
|
16266
16511
|
}
|
|
16267
|
-
await this.persist();
|
|
16512
|
+
await this.persist({ servers: [serverUrl] });
|
|
16268
16513
|
}
|
|
16269
16514
|
async getCodeVerifier(serverUrl) {
|
|
16270
16515
|
await this.ensureLoaded();
|
|
@@ -16274,12 +16519,12 @@ var OAuthStorageBase = class {
|
|
|
16274
16519
|
async saveCodeVerifier(serverUrl, codeVerifier) {
|
|
16275
16520
|
await this.ensureLoaded();
|
|
16276
16521
|
this.memory.getState().setServerState(serverUrl, { codeVerifier });
|
|
16277
|
-
await this.persist();
|
|
16522
|
+
await this.persist({ servers: [serverUrl] });
|
|
16278
16523
|
}
|
|
16279
16524
|
async clearCodeVerifier(serverUrl) {
|
|
16280
16525
|
await this.ensureLoaded();
|
|
16281
16526
|
this.memory.getState().setServerState(serverUrl, { codeVerifier: void 0 });
|
|
16282
|
-
await this.persist();
|
|
16527
|
+
await this.persist({ servers: [serverUrl] });
|
|
16283
16528
|
}
|
|
16284
16529
|
async getScope(serverUrl) {
|
|
16285
16530
|
await this.ensureLoaded();
|
|
@@ -16289,12 +16534,12 @@ var OAuthStorageBase = class {
|
|
|
16289
16534
|
async saveScope(serverUrl, scope) {
|
|
16290
16535
|
await this.ensureLoaded();
|
|
16291
16536
|
this.memory.getState().setServerState(serverUrl, { scope });
|
|
16292
|
-
await this.persist();
|
|
16537
|
+
await this.persist({ servers: [serverUrl] });
|
|
16293
16538
|
}
|
|
16294
16539
|
async clearScope(serverUrl) {
|
|
16295
16540
|
await this.ensureLoaded();
|
|
16296
16541
|
this.memory.getState().setServerState(serverUrl, { scope: void 0 });
|
|
16297
|
-
await this.persist();
|
|
16542
|
+
await this.persist({ servers: [serverUrl] });
|
|
16298
16543
|
}
|
|
16299
16544
|
async getServerMetadata(serverUrl) {
|
|
16300
16545
|
await this.ensureLoaded();
|
|
@@ -16304,12 +16549,12 @@ var OAuthStorageBase = class {
|
|
|
16304
16549
|
async saveServerMetadata(serverUrl, metadata) {
|
|
16305
16550
|
await this.ensureLoaded();
|
|
16306
16551
|
this.memory.getState().setServerState(serverUrl, { serverMetadata: metadata });
|
|
16307
|
-
await this.persist();
|
|
16552
|
+
await this.persist({ servers: [serverUrl] });
|
|
16308
16553
|
}
|
|
16309
16554
|
async clearServerMetadata(serverUrl) {
|
|
16310
16555
|
await this.ensureLoaded();
|
|
16311
16556
|
this.memory.getState().setServerState(serverUrl, { serverMetadata: void 0 });
|
|
16312
|
-
await this.persist();
|
|
16557
|
+
await this.persist({ servers: [serverUrl] });
|
|
16313
16558
|
}
|
|
16314
16559
|
async getDiscoveryState(serverUrl) {
|
|
16315
16560
|
await this.ensureLoaded();
|
|
@@ -16318,12 +16563,12 @@ var OAuthStorageBase = class {
|
|
|
16318
16563
|
async saveDiscoveryState(serverUrl, state) {
|
|
16319
16564
|
await this.ensureLoaded();
|
|
16320
16565
|
this.memory.getState().setServerState(serverUrl, { discoveryState: state });
|
|
16321
|
-
await this.persist();
|
|
16566
|
+
await this.persist({ servers: [serverUrl] });
|
|
16322
16567
|
}
|
|
16323
16568
|
async clearDiscoveryState(serverUrl) {
|
|
16324
16569
|
await this.ensureLoaded();
|
|
16325
16570
|
this.memory.getState().setServerState(serverUrl, { discoveryState: void 0 });
|
|
16326
|
-
await this.persist();
|
|
16571
|
+
await this.persist({ servers: [serverUrl] });
|
|
16327
16572
|
}
|
|
16328
16573
|
async takeRevocationSnapshot(serverUrl) {
|
|
16329
16574
|
await this.ensureLoaded();
|
|
@@ -16341,13 +16586,13 @@ var OAuthStorageBase = class {
|
|
|
16341
16586
|
serverMetadata: state.serverMetadata
|
|
16342
16587
|
};
|
|
16343
16588
|
this.memory.getState().clearServerState(serverUrl);
|
|
16344
|
-
await this.persist();
|
|
16589
|
+
await this.persist({ servers: [serverUrl] });
|
|
16345
16590
|
return snapshot;
|
|
16346
16591
|
}
|
|
16347
16592
|
async clear(serverUrl) {
|
|
16348
16593
|
await this.ensureLoaded();
|
|
16349
16594
|
this.memory.getState().clearServerState(serverUrl);
|
|
16350
|
-
await this.persist();
|
|
16595
|
+
await this.persist({ servers: [serverUrl] });
|
|
16351
16596
|
}
|
|
16352
16597
|
async getIdpSession(issuer) {
|
|
16353
16598
|
await this.ensureLoaded();
|
|
@@ -16360,17 +16605,18 @@ var OAuthStorageBase = class {
|
|
|
16360
16605
|
async saveIdpSession(issuer, session) {
|
|
16361
16606
|
await this.ensureLoaded();
|
|
16362
16607
|
this.memory.getState().setIdpSession(issuer, session);
|
|
16363
|
-
await this.persist();
|
|
16608
|
+
await this.persist({ idpSessions: [issuer] });
|
|
16364
16609
|
}
|
|
16365
16610
|
async clearIdpSession(issuer) {
|
|
16366
16611
|
await this.ensureLoaded();
|
|
16367
16612
|
this.memory.getState().clearIdpSession(issuer);
|
|
16368
|
-
await this.persist();
|
|
16613
|
+
await this.persist({ idpSessions: [issuer] });
|
|
16369
16614
|
}
|
|
16370
16615
|
async clearEnterpriseManagedResourceServers() {
|
|
16371
16616
|
await this.ensureLoaded();
|
|
16617
|
+
const servers = Object.entries(this.memory.getState().servers).filter(([, state]) => state.enterpriseManaged === true).map(([url]) => url);
|
|
16372
16618
|
this.memory.getState().clearEnterpriseManagedResourceServers();
|
|
16373
|
-
await this.persist();
|
|
16619
|
+
await this.persist({ servers });
|
|
16374
16620
|
}
|
|
16375
16621
|
};
|
|
16376
16622
|
|
|
@@ -16388,13 +16634,15 @@ var OAuthMemoryStore = class {
|
|
|
16388
16634
|
servers: this.servers,
|
|
16389
16635
|
idpSessions: this.idpSessions,
|
|
16390
16636
|
getServerState: (serverUrl) => {
|
|
16391
|
-
return this.servers
|
|
16637
|
+
return getOwnEntry(this.servers, serverUrl) || {};
|
|
16392
16638
|
},
|
|
16393
16639
|
setServerState: (serverUrl, updates) => {
|
|
16394
16640
|
this.servers = {
|
|
16395
16641
|
...this.servers,
|
|
16642
|
+
// Computed keys define own properties, so this write is safe for
|
|
16643
|
+
// `__proto__`; only the merge-base read needs the own guard.
|
|
16396
16644
|
[serverUrl]: {
|
|
16397
|
-
...this.servers
|
|
16645
|
+
...getOwnEntry(this.servers, serverUrl),
|
|
16398
16646
|
...updates
|
|
16399
16647
|
}
|
|
16400
16648
|
};
|
|
@@ -16405,13 +16653,13 @@ var OAuthMemoryStore = class {
|
|
|
16405
16653
|
this.servers = rest;
|
|
16406
16654
|
},
|
|
16407
16655
|
getIdpSession: (issuer) => {
|
|
16408
|
-
return this.idpSessions
|
|
16656
|
+
return getOwnEntry(this.idpSessions, issuer) || {};
|
|
16409
16657
|
},
|
|
16410
16658
|
setIdpSession: (issuer, updates) => {
|
|
16411
16659
|
this.idpSessions = {
|
|
16412
16660
|
...this.idpSessions,
|
|
16413
16661
|
[issuer]: {
|
|
16414
|
-
...this.idpSessions
|
|
16662
|
+
...getOwnEntry(this.idpSessions, issuer),
|
|
16415
16663
|
...updates
|
|
16416
16664
|
}
|
|
16417
16665
|
};
|
|
@@ -16445,13 +16693,70 @@ var OAuthMemoryStore = class {
|
|
|
16445
16693
|
};
|
|
16446
16694
|
|
|
16447
16695
|
// ../../core/auth/oauth-persist.ts
|
|
16696
|
+
import { OAuthTokensSchema as OAuthTokensSchema4 } from "@modelcontextprotocol/core";
|
|
16697
|
+
function mergeOAuthSections(disk, snapshot, sections) {
|
|
16698
|
+
const merged = {
|
|
16699
|
+
servers: { ...disk?.servers },
|
|
16700
|
+
idpSessions: { ...disk?.idpSessions }
|
|
16701
|
+
};
|
|
16702
|
+
for (const url of sections.servers ?? []) {
|
|
16703
|
+
const value = getOwnEntry(snapshot.servers, url);
|
|
16704
|
+
if (value === void 0) {
|
|
16705
|
+
delete merged.servers[url];
|
|
16706
|
+
} else {
|
|
16707
|
+
setOwnEntry(merged.servers, url, value);
|
|
16708
|
+
}
|
|
16709
|
+
}
|
|
16710
|
+
for (const issuer of sections.idpSessions ?? []) {
|
|
16711
|
+
const value = getOwnEntry(snapshot.idpSessions, issuer);
|
|
16712
|
+
if (value === void 0) {
|
|
16713
|
+
delete merged.idpSessions[issuer];
|
|
16714
|
+
} else {
|
|
16715
|
+
setOwnEntry(merged.idpSessions, issuer, value);
|
|
16716
|
+
}
|
|
16717
|
+
}
|
|
16718
|
+
return merged;
|
|
16719
|
+
}
|
|
16448
16720
|
function isRecord4(value) {
|
|
16449
16721
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16450
16722
|
}
|
|
16723
|
+
function isEntryMap(value) {
|
|
16724
|
+
return isRecord4(value) && Object.values(value).every(isRecord4);
|
|
16725
|
+
}
|
|
16726
|
+
var VERBATIM_SECRET_KEYS = [
|
|
16727
|
+
"client_secret",
|
|
16728
|
+
"registration_access_token"
|
|
16729
|
+
];
|
|
16730
|
+
function isValidClientInformation(value) {
|
|
16731
|
+
if (value === void 0) return true;
|
|
16732
|
+
if (!isRecord4(value)) return false;
|
|
16733
|
+
return VERBATIM_SECRET_KEYS.every(
|
|
16734
|
+
(key) => !Object.hasOwn(value, key) || typeof value[key] === "string"
|
|
16735
|
+
);
|
|
16736
|
+
}
|
|
16737
|
+
var PartialTokensSchema = OAuthTokensSchema4.partial();
|
|
16738
|
+
function isValidServerEntry(entry) {
|
|
16739
|
+
if (!isRecord4(entry)) return false;
|
|
16740
|
+
if (!isValidClientInformation(entry.clientInformation)) return false;
|
|
16741
|
+
if (!isValidClientInformation(entry.preregisteredClientInformation))
|
|
16742
|
+
return false;
|
|
16743
|
+
if (entry.byIssuer !== void 0) {
|
|
16744
|
+
if (!isRecord4(entry.byIssuer)) return false;
|
|
16745
|
+
for (const slot of Object.values(entry.byIssuer)) {
|
|
16746
|
+
if (!isRecord4(slot)) return false;
|
|
16747
|
+
if (!isValidClientInformation(slot.clientInformation)) return false;
|
|
16748
|
+
}
|
|
16749
|
+
}
|
|
16750
|
+
return true;
|
|
16751
|
+
}
|
|
16451
16752
|
function snapshotFromPayload(payload) {
|
|
16753
|
+
const servers = payload.servers ?? {};
|
|
16754
|
+
const idpSessions = payload.idpSessions ?? {};
|
|
16755
|
+
if (!isEntryMap(servers) || !isEntryMap(idpSessions)) return null;
|
|
16756
|
+
if (!Object.values(servers).every(isValidServerEntry)) return null;
|
|
16452
16757
|
return {
|
|
16453
|
-
servers
|
|
16454
|
-
idpSessions
|
|
16758
|
+
servers,
|
|
16759
|
+
idpSessions
|
|
16455
16760
|
};
|
|
16456
16761
|
}
|
|
16457
16762
|
function parseOAuthPersistBlob(raw) {
|
|
@@ -16474,92 +16779,853 @@ function serializeOAuthPersistBlob(snapshot) {
|
|
|
16474
16779
|
return serializeStore(snapshot);
|
|
16475
16780
|
}
|
|
16476
16781
|
|
|
16477
|
-
// ../../core/auth/node/oauth-
|
|
16478
|
-
|
|
16782
|
+
// ../../core/auth/node/oauth-secrets.ts
|
|
16783
|
+
import { OAuthTokensSchema as OAuthTokensSchema5 } from "@modelcontextprotocol/core";
|
|
16784
|
+
var PERSIST_TOKENS_ENV = "MCP_INSPECTOR_PERSIST_TOKENS";
|
|
16785
|
+
var warnedPolicyValues = /* @__PURE__ */ new Set();
|
|
16786
|
+
function getPersistTokensPolicy(env2 = process.env) {
|
|
16787
|
+
const raw = env2[PERSIST_TOKENS_ENV];
|
|
16788
|
+
if (raw === void 0 || raw === "") return "all";
|
|
16789
|
+
if (raw === "all" || raw === "access" || raw === "none") return raw;
|
|
16790
|
+
if (!warnedPolicyValues.has(raw)) {
|
|
16791
|
+
warnedPolicyValues.add(raw);
|
|
16792
|
+
console.warn(
|
|
16793
|
+
`[mcp-inspector] Ignoring invalid ${PERSIST_TOKENS_ENV}=${JSON.stringify(raw)} (expected "all", "access", or "none"); persisting all tokens.`
|
|
16794
|
+
);
|
|
16795
|
+
}
|
|
16796
|
+
return "all";
|
|
16797
|
+
}
|
|
16798
|
+
var oauthSecretServerId = (serverUrl) => `oauth+${encodeURIComponent(serverUrl)}`;
|
|
16799
|
+
var oauthIdpSecretServerId = (issuer) => `oauth-idp+${encodeURIComponent(issuer)}`;
|
|
16800
|
+
var issuerTokensField = (issuer) => `tokens:${issuer}`;
|
|
16801
|
+
var issuerClientSecretField = (issuer) => `client-secret:${issuer}`;
|
|
16802
|
+
var issuerRegistrationTokenField = (issuer) => `registration-token:${issuer}`;
|
|
16803
|
+
var LEGACY_TOKENS_FIELD = "tokens";
|
|
16804
|
+
var LEGACY_CLIENT_SECRET_FIELD = "client-secret";
|
|
16805
|
+
var LEGACY_REGISTRATION_TOKEN_FIELD = "registration-token";
|
|
16806
|
+
var PREREG_CLIENT_SECRET_FIELD = "prereg-client-secret";
|
|
16807
|
+
var PREREG_REGISTRATION_TOKEN_FIELD = "prereg-registration-token";
|
|
16808
|
+
var IDP_SESSION_FIELD = "idp-session";
|
|
16809
|
+
function applyTokensPolicy(tokens, policy) {
|
|
16810
|
+
if (policy === "none") return void 0;
|
|
16811
|
+
if (policy === "access" && tokens.refresh_token !== void 0) {
|
|
16812
|
+
const { refresh_token: _stripped, ...rest } = tokens;
|
|
16813
|
+
return rest;
|
|
16814
|
+
}
|
|
16815
|
+
return tokens;
|
|
16816
|
+
}
|
|
16817
|
+
var StorableTokensSchema = OAuthTokensSchema5.partial();
|
|
16818
|
+
function hasSecretBearingTokenField(tokens) {
|
|
16819
|
+
return tokens.access_token !== void 0 || tokens.refresh_token !== void 0 || tokens.id_token !== void 0;
|
|
16820
|
+
}
|
|
16821
|
+
function splitTokens(tokens, policy) {
|
|
16822
|
+
const kept = applyTokensPolicy(tokens, policy);
|
|
16823
|
+
if (!kept) return {};
|
|
16824
|
+
if (!StorableTokensSchema.safeParse(kept).success) {
|
|
16825
|
+
return { plaintext: kept };
|
|
16826
|
+
}
|
|
16827
|
+
if (!hasSecretBearingTokenField(kept)) {
|
|
16828
|
+
return {};
|
|
16829
|
+
}
|
|
16830
|
+
return { secret: JSON.stringify(kept) };
|
|
16831
|
+
}
|
|
16832
|
+
function splitClientInformation(info, fields, secrets) {
|
|
16833
|
+
const { client_secret, registration_access_token, ...publicInfo } = info;
|
|
16834
|
+
if (client_secret === void 0 && registration_access_token === void 0) {
|
|
16835
|
+
return info;
|
|
16836
|
+
}
|
|
16837
|
+
if (client_secret !== void 0) {
|
|
16838
|
+
secrets[fields.clientSecret] = client_secret;
|
|
16839
|
+
}
|
|
16840
|
+
if (registration_access_token !== void 0) {
|
|
16841
|
+
secrets[fields.registrationToken] = registration_access_token;
|
|
16842
|
+
}
|
|
16843
|
+
return publicInfo;
|
|
16844
|
+
}
|
|
16845
|
+
function joinClientInformation(info, fields, secrets) {
|
|
16846
|
+
const clientSecret = secrets[fields.clientSecret];
|
|
16847
|
+
const registrationToken = secrets[fields.registrationToken];
|
|
16848
|
+
if (clientSecret === void 0 && registrationToken === void 0) {
|
|
16849
|
+
return info;
|
|
16850
|
+
}
|
|
16479
16851
|
return {
|
|
16480
|
-
|
|
16481
|
-
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
async write(snapshot) {
|
|
16485
|
-
await writeStoreFile(
|
|
16486
|
-
options.filePath,
|
|
16487
|
-
serializeOAuthPersistBlob(snapshot)
|
|
16488
|
-
);
|
|
16489
|
-
},
|
|
16490
|
-
async remove() {
|
|
16491
|
-
await deleteStoreFile(options.filePath);
|
|
16852
|
+
...info,
|
|
16853
|
+
...clientSecret !== void 0 && { client_secret: clientSecret },
|
|
16854
|
+
...registrationToken !== void 0 && {
|
|
16855
|
+
registration_access_token: registrationToken
|
|
16492
16856
|
}
|
|
16493
16857
|
};
|
|
16494
16858
|
}
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16859
|
+
var issuerClientInfoFields = (issuer) => ({
|
|
16860
|
+
clientSecret: issuerClientSecretField(issuer),
|
|
16861
|
+
registrationToken: issuerRegistrationTokenField(issuer)
|
|
16862
|
+
});
|
|
16863
|
+
var LEGACY_CLIENT_INFO_FIELDS = {
|
|
16864
|
+
clientSecret: LEGACY_CLIENT_SECRET_FIELD,
|
|
16865
|
+
registrationToken: LEGACY_REGISTRATION_TOKEN_FIELD
|
|
16866
|
+
};
|
|
16867
|
+
var PREREG_CLIENT_INFO_FIELDS = {
|
|
16868
|
+
clientSecret: PREREG_CLIENT_SECRET_FIELD,
|
|
16869
|
+
registrationToken: PREREG_REGISTRATION_TOKEN_FIELD
|
|
16870
|
+
};
|
|
16871
|
+
function splitServerOAuthState(state, policy) {
|
|
16872
|
+
const secrets = {};
|
|
16873
|
+
const residue = { ...state };
|
|
16874
|
+
if (state.byIssuer) {
|
|
16875
|
+
const byIssuer = {};
|
|
16876
|
+
for (const [issuer, slot] of Object.entries(state.byIssuer)) {
|
|
16877
|
+
const slotResidue = { ...slot };
|
|
16878
|
+
if (slot.tokens) {
|
|
16879
|
+
delete slotResidue.tokens;
|
|
16880
|
+
const tokenSplit = splitTokens(slot.tokens, policy);
|
|
16881
|
+
if (tokenSplit.secret !== void 0) {
|
|
16882
|
+
secrets[issuerTokensField(issuer)] = tokenSplit.secret;
|
|
16883
|
+
}
|
|
16884
|
+
if (tokenSplit.plaintext) slotResidue.tokens = tokenSplit.plaintext;
|
|
16885
|
+
}
|
|
16886
|
+
if (slot.clientInformation) {
|
|
16887
|
+
slotResidue.clientInformation = splitClientInformation(
|
|
16888
|
+
slot.clientInformation,
|
|
16889
|
+
issuerClientInfoFields(issuer),
|
|
16890
|
+
secrets
|
|
16891
|
+
);
|
|
16892
|
+
}
|
|
16893
|
+
setOwnEntry(byIssuer, issuer, slotResidue);
|
|
16894
|
+
}
|
|
16895
|
+
residue.byIssuer = byIssuer;
|
|
16502
16896
|
}
|
|
16503
|
-
if (
|
|
16504
|
-
|
|
16897
|
+
if (state.tokens) {
|
|
16898
|
+
delete residue.tokens;
|
|
16899
|
+
const tokenSplit = splitTokens(state.tokens, policy);
|
|
16900
|
+
if (tokenSplit.secret !== void 0) {
|
|
16901
|
+
secrets[LEGACY_TOKENS_FIELD] = tokenSplit.secret;
|
|
16902
|
+
}
|
|
16903
|
+
if (tokenSplit.plaintext) residue.tokens = tokenSplit.plaintext;
|
|
16505
16904
|
}
|
|
16506
|
-
|
|
16905
|
+
if (state.clientInformation) {
|
|
16906
|
+
residue.clientInformation = splitClientInformation(
|
|
16907
|
+
state.clientInformation,
|
|
16908
|
+
LEGACY_CLIENT_INFO_FIELDS,
|
|
16909
|
+
secrets
|
|
16910
|
+
);
|
|
16911
|
+
}
|
|
16912
|
+
if (state.preregisteredClientInformation) {
|
|
16913
|
+
residue.preregisteredClientInformation = splitClientInformation(
|
|
16914
|
+
state.preregisteredClientInformation,
|
|
16915
|
+
PREREG_CLIENT_INFO_FIELDS,
|
|
16916
|
+
secrets
|
|
16917
|
+
);
|
|
16918
|
+
}
|
|
16919
|
+
return { residue, secrets };
|
|
16507
16920
|
}
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16921
|
+
function parseStoredTokens(raw) {
|
|
16922
|
+
try {
|
|
16923
|
+
const parsed = JSON.parse(raw);
|
|
16924
|
+
if (StorableTokensSchema.safeParse(parsed).success && hasSecretBearingTokenField(parsed)) {
|
|
16925
|
+
return parsed;
|
|
16926
|
+
}
|
|
16927
|
+
} catch {
|
|
16515
16928
|
}
|
|
16516
|
-
return
|
|
16929
|
+
return void 0;
|
|
16517
16930
|
}
|
|
16518
|
-
|
|
16519
|
-
|
|
16520
|
-
|
|
16521
|
-
|
|
16522
|
-
|
|
16523
|
-
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16931
|
+
function parseStoredIdpSession(raw) {
|
|
16932
|
+
try {
|
|
16933
|
+
const parsed = JSON.parse(raw);
|
|
16934
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
16935
|
+
const { idToken, refreshToken } = parsed;
|
|
16936
|
+
const usable = {
|
|
16937
|
+
...typeof idToken === "string" && { idToken },
|
|
16938
|
+
...typeof refreshToken === "string" && { refreshToken }
|
|
16939
|
+
};
|
|
16940
|
+
if (Object.keys(usable).length > 0) return usable;
|
|
16941
|
+
}
|
|
16942
|
+
} catch {
|
|
16528
16943
|
}
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
// ../../core/auth/node/oauth-callback-server.ts
|
|
16532
|
-
import { createServer } from "http";
|
|
16533
|
-
var DEFAULT_HOSTNAME = "127.0.0.1";
|
|
16534
|
-
var DEFAULT_CALLBACK_PATH = "/oauth/callback";
|
|
16535
|
-
var SUCCESS_HTML = `<!DOCTYPE html>
|
|
16536
|
-
<html>
|
|
16537
|
-
<head><meta charset="utf-8"><title>OAuth complete</title></head>
|
|
16538
|
-
<body><p>OAuth complete. You can close this window.</p></body>
|
|
16539
|
-
</html>`;
|
|
16540
|
-
function errorHtml(message) {
|
|
16541
|
-
return `<!DOCTYPE html>
|
|
16542
|
-
<html>
|
|
16543
|
-
<head><meta charset="utf-8"><title>OAuth error</title></head>
|
|
16544
|
-
<body><p>OAuth failed: ${escapeHtml(message)}</p></body>
|
|
16545
|
-
</html>`;
|
|
16944
|
+
return void 0;
|
|
16546
16945
|
}
|
|
16547
|
-
function
|
|
16548
|
-
|
|
16946
|
+
function isUsableStoredSecret(field, raw) {
|
|
16947
|
+
if (field === LEGACY_TOKENS_FIELD || field.startsWith("tokens:")) {
|
|
16948
|
+
return parseStoredTokens(raw) !== void 0;
|
|
16949
|
+
}
|
|
16950
|
+
if (field === IDP_SESSION_FIELD) {
|
|
16951
|
+
return parseStoredIdpSession(raw) !== void 0;
|
|
16952
|
+
}
|
|
16953
|
+
return true;
|
|
16549
16954
|
}
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16955
|
+
function joinServerOAuthState(residue, secrets) {
|
|
16956
|
+
const joined = { ...residue };
|
|
16957
|
+
if (residue.byIssuer) {
|
|
16958
|
+
const byIssuer = {};
|
|
16959
|
+
for (const [issuer, slot] of Object.entries(residue.byIssuer)) {
|
|
16960
|
+
const joinedSlot = { ...slot };
|
|
16961
|
+
const tokensRaw = secrets[issuerTokensField(issuer)];
|
|
16962
|
+
if (tokensRaw !== void 0) {
|
|
16963
|
+
const tokens = parseStoredTokens(tokensRaw);
|
|
16964
|
+
if (tokens) joinedSlot.tokens = tokens;
|
|
16965
|
+
}
|
|
16966
|
+
if (joinedSlot.clientInformation) {
|
|
16967
|
+
joinedSlot.clientInformation = joinClientInformation(
|
|
16968
|
+
joinedSlot.clientInformation,
|
|
16969
|
+
issuerClientInfoFields(issuer),
|
|
16970
|
+
secrets
|
|
16971
|
+
);
|
|
16972
|
+
}
|
|
16973
|
+
setOwnEntry(byIssuer, issuer, joinedSlot);
|
|
16974
|
+
}
|
|
16975
|
+
joined.byIssuer = byIssuer;
|
|
16976
|
+
}
|
|
16977
|
+
const legacyTokensRaw = secrets[LEGACY_TOKENS_FIELD];
|
|
16978
|
+
if (legacyTokensRaw !== void 0) {
|
|
16979
|
+
const tokens = parseStoredTokens(legacyTokensRaw);
|
|
16980
|
+
if (tokens) joined.tokens = tokens;
|
|
16981
|
+
}
|
|
16982
|
+
if (joined.clientInformation) {
|
|
16983
|
+
joined.clientInformation = joinClientInformation(
|
|
16984
|
+
joined.clientInformation,
|
|
16985
|
+
LEGACY_CLIENT_INFO_FIELDS,
|
|
16986
|
+
secrets
|
|
16987
|
+
);
|
|
16988
|
+
}
|
|
16989
|
+
if (joined.preregisteredClientInformation) {
|
|
16990
|
+
joined.preregisteredClientInformation = joinClientInformation(
|
|
16991
|
+
joined.preregisteredClientInformation,
|
|
16992
|
+
PREREG_CLIENT_INFO_FIELDS,
|
|
16993
|
+
secrets
|
|
16994
|
+
);
|
|
16995
|
+
}
|
|
16996
|
+
return joined;
|
|
16997
|
+
}
|
|
16998
|
+
function splitIdpSession(session, policy) {
|
|
16999
|
+
const { idToken, refreshToken, ...residue } = session;
|
|
17000
|
+
const secrets = {};
|
|
17001
|
+
if (policy !== "none" && (idToken !== void 0 || refreshToken !== void 0)) {
|
|
17002
|
+
const kept = {
|
|
17003
|
+
...typeof idToken === "string" && { idToken },
|
|
17004
|
+
...policy === "all" && typeof refreshToken === "string" && { refreshToken }
|
|
17005
|
+
};
|
|
17006
|
+
if (Object.keys(kept).length > 0) {
|
|
17007
|
+
secrets[IDP_SESSION_FIELD] = JSON.stringify(kept);
|
|
17008
|
+
}
|
|
17009
|
+
}
|
|
17010
|
+
return { residue, secrets };
|
|
17011
|
+
}
|
|
17012
|
+
function joinIdpSession(residue, secrets) {
|
|
17013
|
+
const raw = secrets[IDP_SESSION_FIELD];
|
|
17014
|
+
if (raw === void 0) return { ...residue };
|
|
17015
|
+
const stored = parseStoredIdpSession(raw);
|
|
17016
|
+
return stored ? { ...residue, ...stored } : { ...residue };
|
|
17017
|
+
}
|
|
17018
|
+
function serverSecretFields(state) {
|
|
17019
|
+
const fields = /* @__PURE__ */ new Set([
|
|
17020
|
+
LEGACY_TOKENS_FIELD,
|
|
17021
|
+
LEGACY_CLIENT_SECRET_FIELD,
|
|
17022
|
+
LEGACY_REGISTRATION_TOKEN_FIELD,
|
|
17023
|
+
PREREG_CLIENT_SECRET_FIELD,
|
|
17024
|
+
PREREG_REGISTRATION_TOKEN_FIELD
|
|
17025
|
+
]);
|
|
17026
|
+
for (const issuer of Object.keys(state?.byIssuer ?? {})) {
|
|
17027
|
+
fields.add(issuerTokensField(issuer));
|
|
17028
|
+
fields.add(issuerClientSecretField(issuer));
|
|
17029
|
+
fields.add(issuerRegistrationTokenField(issuer));
|
|
17030
|
+
}
|
|
17031
|
+
return [...fields];
|
|
17032
|
+
}
|
|
17033
|
+
function clientInfoHasPlaintext(info) {
|
|
17034
|
+
return info !== void 0 && (info.client_secret !== void 0 || info.registration_access_token !== void 0);
|
|
17035
|
+
}
|
|
17036
|
+
function snapshotHasPlaintextSecrets(snapshot) {
|
|
17037
|
+
for (const state of Object.values(snapshot.servers)) {
|
|
17038
|
+
if (state.tokens) return true;
|
|
17039
|
+
if (clientInfoHasPlaintext(state.clientInformation)) return true;
|
|
17040
|
+
if (clientInfoHasPlaintext(state.preregisteredClientInformation)) {
|
|
17041
|
+
return true;
|
|
17042
|
+
}
|
|
17043
|
+
for (const slot of Object.values(state.byIssuer ?? {})) {
|
|
17044
|
+
if (slot.tokens) return true;
|
|
17045
|
+
if (clientInfoHasPlaintext(slot.clientInformation)) return true;
|
|
17046
|
+
}
|
|
17047
|
+
}
|
|
17048
|
+
for (const session of Object.values(snapshot.idpSessions)) {
|
|
17049
|
+
if (session.idToken !== void 0 || session.refreshToken !== void 0) {
|
|
17050
|
+
return true;
|
|
17051
|
+
}
|
|
17052
|
+
}
|
|
17053
|
+
return false;
|
|
17054
|
+
}
|
|
17055
|
+
|
|
17056
|
+
// ../../core/auth/node/oauth-persist-file.ts
|
|
17057
|
+
var warnedStoreFailures = /* @__PURE__ */ new Set();
|
|
17058
|
+
function warnStoreWriteFailure(error) {
|
|
17059
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
17060
|
+
if (warnedStoreFailures.has(reason)) return;
|
|
17061
|
+
warnedStoreFailures.add(reason);
|
|
17062
|
+
console.warn(
|
|
17063
|
+
`[mcp-inspector] Could not write OAuth tokens to the secret store (${reason}). Tokens will be kept in memory for this session only and will NOT be persisted; expect to re-authorize after a restart.`
|
|
17064
|
+
);
|
|
17065
|
+
}
|
|
17066
|
+
function warnRestoreFailure(error) {
|
|
17067
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
17068
|
+
const key = `restore:${reason}`;
|
|
17069
|
+
if (warnedStoreFailures.has(key)) return;
|
|
17070
|
+
warnedStoreFailures.add(key);
|
|
17071
|
+
console.warn(
|
|
17072
|
+
`[mcp-inspector] Could not restore secret-store entries after a failed OAuth state write (${reason}). The secret store may be inconsistent with oauth.json; if a server's stored credentials stop working, re-authorize it.`
|
|
17073
|
+
);
|
|
17074
|
+
}
|
|
17075
|
+
function warnUnconfirmedFile(error) {
|
|
17076
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
17077
|
+
const key = `unconfirmed:${reason}`;
|
|
17078
|
+
if (warnedStoreFailures.has(key)) return;
|
|
17079
|
+
warnedStoreFailures.add(key);
|
|
17080
|
+
console.warn(
|
|
17081
|
+
`[mcp-inspector] Could not re-read oauth.json after a failed OAuth state save (${reason}). The file may still contain the interrupted save while the secret store was restored to the previous values; if a server's stored credentials stop working, re-authorize it.`
|
|
17082
|
+
);
|
|
17083
|
+
}
|
|
17084
|
+
function warnMigrationFailure(error) {
|
|
17085
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
17086
|
+
const key = `migration:${reason}`;
|
|
17087
|
+
if (warnedStoreFailures.has(key)) return;
|
|
17088
|
+
warnedStoreFailures.add(key);
|
|
17089
|
+
console.warn(
|
|
17090
|
+
`[mcp-inspector] Could not migrate plaintext OAuth secrets into the secret store (${reason}). The plaintext copy in oauth.json was kept and keeps working; migration will be retried on the next read.`
|
|
17091
|
+
);
|
|
17092
|
+
}
|
|
17093
|
+
function rethrowLockError(filePath, error, action = "save") {
|
|
17094
|
+
if (error instanceof SecretFileLockHeldError) {
|
|
17095
|
+
throw new SecretFileLockHeldError(
|
|
17096
|
+
`Could not ${action} OAuth state: the state file at ${filePath} is locked by another Inspector process and did not become available.`,
|
|
17097
|
+
{ cause: error }
|
|
17098
|
+
);
|
|
17099
|
+
}
|
|
17100
|
+
throw error;
|
|
17101
|
+
}
|
|
17102
|
+
async function withOAuthStateLock(filePath, action, body) {
|
|
17103
|
+
let entered = false;
|
|
17104
|
+
try {
|
|
17105
|
+
return await withSecretFileLock(filePath, async () => {
|
|
17106
|
+
entered = true;
|
|
17107
|
+
return body();
|
|
17108
|
+
});
|
|
17109
|
+
} catch (error) {
|
|
17110
|
+
if (!entered) rethrowLockError(filePath, error, action);
|
|
17111
|
+
throw error;
|
|
17112
|
+
}
|
|
17113
|
+
}
|
|
17114
|
+
var OAuthStateFileUnrecognizedError = class extends Error {
|
|
17115
|
+
constructor(filePath, action) {
|
|
17116
|
+
super(
|
|
17117
|
+
`Refusing to ${action} OAuth state: ${filePath} exists but is not a recognized OAuth state file (it may be corrupt, truncated, or written by something else). Its entries are the only index of credentials in the OS keychain / secret store, so overwriting it would strand them. Restore the file from a backup or fix its JSON; deleting it starts fresh but abandons any credentials it indexed.`
|
|
17118
|
+
);
|
|
17119
|
+
this.name = "OAuthStateFileUnrecognizedError";
|
|
17120
|
+
}
|
|
17121
|
+
};
|
|
17122
|
+
async function readDiskForMutation(filePath, action) {
|
|
17123
|
+
const raw = await readStoreFile(filePath);
|
|
17124
|
+
const parsed = parseOAuthPersistBlob(raw);
|
|
17125
|
+
if (raw !== null && parsed === null) {
|
|
17126
|
+
throw new OAuthStateFileUnrecognizedError(filePath, action);
|
|
17127
|
+
}
|
|
17128
|
+
return parsed;
|
|
17129
|
+
}
|
|
17130
|
+
async function persistEntrySecrets(store, serverId, candidates, secrets, prior, allowDegrade) {
|
|
17131
|
+
const priorValue = new Map(prior.map(({ field, value }) => [field, value]));
|
|
17132
|
+
const changed = {};
|
|
17133
|
+
for (const [field, value] of Object.entries(secrets)) {
|
|
17134
|
+
if (priorValue.get(field) !== value) changed[field] = value;
|
|
17135
|
+
}
|
|
17136
|
+
try {
|
|
17137
|
+
if (Object.keys(changed).length > 0) {
|
|
17138
|
+
await secretStoreSetMany(store, serverId, changed);
|
|
17139
|
+
}
|
|
17140
|
+
} catch (error) {
|
|
17141
|
+
if (!allowDegrade) throw error;
|
|
17142
|
+
warnStoreWriteFailure(error);
|
|
17143
|
+
const touched = prior.filter(({ field }) => changed[field] !== void 0);
|
|
17144
|
+
let restoreFailure;
|
|
17145
|
+
await restoreSecretFields(store, touched, (err) => {
|
|
17146
|
+
restoreFailure = err;
|
|
17147
|
+
});
|
|
17148
|
+
if (restoreFailure !== void 0) throw restoreFailure;
|
|
17149
|
+
return false;
|
|
17150
|
+
}
|
|
17151
|
+
await settleStoreMutations(
|
|
17152
|
+
candidates.filter(
|
|
17153
|
+
(field) => secrets[field] === void 0 && priorValue.get(field) !== null
|
|
17154
|
+
).map((field) => store.delete(serverId, field))
|
|
17155
|
+
);
|
|
17156
|
+
return true;
|
|
17157
|
+
}
|
|
17158
|
+
function revertEntryToDisk(merged, disk, key) {
|
|
17159
|
+
const diskEntry = getOwnEntry(disk, key);
|
|
17160
|
+
if (diskEntry === void 0) {
|
|
17161
|
+
if (Object.hasOwn(merged, key)) delete merged[key];
|
|
17162
|
+
} else {
|
|
17163
|
+
setOwnEntry(merged, key, diskEntry);
|
|
17164
|
+
}
|
|
17165
|
+
}
|
|
17166
|
+
function preserveNonDurableSecrets(diskSecrets, secrets) {
|
|
17167
|
+
const keep = {};
|
|
17168
|
+
for (const [field, value] of Object.entries(secrets)) {
|
|
17169
|
+
if (diskSecrets[field] === value) keep[field] = value;
|
|
17170
|
+
}
|
|
17171
|
+
return keep;
|
|
17172
|
+
}
|
|
17173
|
+
async function writeOAuthSections(filePath, snapshot, sections, secretStore = defaultSecretStore()) {
|
|
17174
|
+
const policy = getPersistTokensPolicy();
|
|
17175
|
+
const durable = await secretStoreIsDurable(secretStore);
|
|
17176
|
+
await withOAuthStateLock(filePath, "save", async () => {
|
|
17177
|
+
const restoreBaseline = /* @__PURE__ */ new Map();
|
|
17178
|
+
const ourWrites = /* @__PURE__ */ new Map();
|
|
17179
|
+
const priorKey = (p) => `${p.serverId}\0${p.field}`;
|
|
17180
|
+
const foldPriors = (priors) => {
|
|
17181
|
+
for (const prior of priors) {
|
|
17182
|
+
const key = priorKey(prior);
|
|
17183
|
+
if (restoreBaseline.has(key) && ourWrites.get(key) !== void 0 && prior.value === ourWrites.get(key)) {
|
|
17184
|
+
continue;
|
|
17185
|
+
}
|
|
17186
|
+
restoreBaseline.set(key, prior);
|
|
17187
|
+
}
|
|
17188
|
+
};
|
|
17189
|
+
const restoreToBaseline = () => restoreSecretFields(
|
|
17190
|
+
secretStore,
|
|
17191
|
+
[...restoreBaseline.values()],
|
|
17192
|
+
warnRestoreFailure
|
|
17193
|
+
);
|
|
17194
|
+
let unconfirmed = null;
|
|
17195
|
+
const reconcileFailure = async () => {
|
|
17196
|
+
if (unconfirmed !== null) {
|
|
17197
|
+
const committed = unconfirmed;
|
|
17198
|
+
let observed = null;
|
|
17199
|
+
let readable = true;
|
|
17200
|
+
try {
|
|
17201
|
+
observed = await readStoreFile(filePath);
|
|
17202
|
+
} catch (error) {
|
|
17203
|
+
readable = false;
|
|
17204
|
+
warnUnconfirmedFile(error);
|
|
17205
|
+
}
|
|
17206
|
+
if (readable && observed === committed.written) {
|
|
17207
|
+
const target = new Map(
|
|
17208
|
+
[...restoreBaseline].map(([key, { serverId, field, value }]) => [
|
|
17209
|
+
key,
|
|
17210
|
+
{ serverId, field, value }
|
|
17211
|
+
])
|
|
17212
|
+
);
|
|
17213
|
+
for (const [key, write] of committed.writes) target.set(key, write);
|
|
17214
|
+
try {
|
|
17215
|
+
await settleStoreMutations(
|
|
17216
|
+
[...target.values()].map(
|
|
17217
|
+
({ serverId, field, value }) => value === null ? secretStore.delete(serverId, field) : secretStore.set(serverId, field, value)
|
|
17218
|
+
)
|
|
17219
|
+
);
|
|
17220
|
+
return true;
|
|
17221
|
+
} catch (error) {
|
|
17222
|
+
warnRestoreFailure(error);
|
|
17223
|
+
return false;
|
|
17224
|
+
}
|
|
17225
|
+
}
|
|
17226
|
+
}
|
|
17227
|
+
await restoreToBaseline();
|
|
17228
|
+
return false;
|
|
17229
|
+
};
|
|
17230
|
+
for (let attempt = 0; attempt < MAX_WRITE_ATTEMPTS; attempt++) {
|
|
17231
|
+
const priorSecrets = [];
|
|
17232
|
+
const attemptWrites = /* @__PURE__ */ new Map();
|
|
17233
|
+
let written;
|
|
17234
|
+
try {
|
|
17235
|
+
const disk = await readDiskForMutation(filePath, "save");
|
|
17236
|
+
const effective = sections ? {
|
|
17237
|
+
servers: sections.servers && [...new Set(sections.servers)],
|
|
17238
|
+
idpSessions: sections.idpSessions && [
|
|
17239
|
+
...new Set(sections.idpSessions)
|
|
17240
|
+
]
|
|
17241
|
+
} : {
|
|
17242
|
+
servers: [
|
|
17243
|
+
.../* @__PURE__ */ new Set([
|
|
17244
|
+
...Object.keys(disk?.servers ?? {}),
|
|
17245
|
+
...Object.keys(snapshot.servers)
|
|
17246
|
+
])
|
|
17247
|
+
],
|
|
17248
|
+
idpSessions: [
|
|
17249
|
+
.../* @__PURE__ */ new Set([
|
|
17250
|
+
...Object.keys(disk?.idpSessions ?? {}),
|
|
17251
|
+
...Object.keys(snapshot.idpSessions)
|
|
17252
|
+
])
|
|
17253
|
+
]
|
|
17254
|
+
};
|
|
17255
|
+
const merged = mergeOAuthSections(disk, snapshot, effective);
|
|
17256
|
+
for (const url of effective.servers ?? []) {
|
|
17257
|
+
const serverId = oauthSecretServerId(url);
|
|
17258
|
+
const next = getOwnEntry(snapshot.servers, url);
|
|
17259
|
+
const candidates = [
|
|
17260
|
+
.../* @__PURE__ */ new Set([
|
|
17261
|
+
...serverSecretFields(getOwnEntry(disk?.servers, url)),
|
|
17262
|
+
...serverSecretFields(next)
|
|
17263
|
+
])
|
|
17264
|
+
];
|
|
17265
|
+
const entryPrior = await snapshotSecretFields(
|
|
17266
|
+
secretStore,
|
|
17267
|
+
serverId,
|
|
17268
|
+
candidates
|
|
17269
|
+
);
|
|
17270
|
+
priorSecrets.push(...entryPrior);
|
|
17271
|
+
if (next === void 0) {
|
|
17272
|
+
for (const field of candidates) {
|
|
17273
|
+
ourWrites.set(priorKey({ serverId, field }), null);
|
|
17274
|
+
}
|
|
17275
|
+
await secretStore.deleteAllForServer(serverId);
|
|
17276
|
+
for (const field of candidates) {
|
|
17277
|
+
attemptWrites.set(priorKey({ serverId, field }), {
|
|
17278
|
+
serverId,
|
|
17279
|
+
field,
|
|
17280
|
+
value: null
|
|
17281
|
+
});
|
|
17282
|
+
}
|
|
17283
|
+
continue;
|
|
17284
|
+
}
|
|
17285
|
+
const { residue, secrets } = splitServerOAuthState(next, policy);
|
|
17286
|
+
for (const field of candidates) {
|
|
17287
|
+
ourWrites.set(
|
|
17288
|
+
priorKey({ serverId, field }),
|
|
17289
|
+
secrets[field] ?? null
|
|
17290
|
+
);
|
|
17291
|
+
}
|
|
17292
|
+
setOwnEntry(merged.servers, url, residue);
|
|
17293
|
+
if (!durable) {
|
|
17294
|
+
const diskEntry = getOwnEntry(disk?.servers, url);
|
|
17295
|
+
const keep = preserveNonDurableSecrets(
|
|
17296
|
+
diskEntry ? splitServerOAuthState(diskEntry, policy).secrets : {},
|
|
17297
|
+
secrets
|
|
17298
|
+
);
|
|
17299
|
+
if (Object.keys(keep).length > 0) {
|
|
17300
|
+
setOwnEntry(
|
|
17301
|
+
merged.servers,
|
|
17302
|
+
url,
|
|
17303
|
+
joinServerOAuthState(residue, keep)
|
|
17304
|
+
);
|
|
17305
|
+
}
|
|
17306
|
+
}
|
|
17307
|
+
const persisted = await persistEntrySecrets(
|
|
17308
|
+
secretStore,
|
|
17309
|
+
serverId,
|
|
17310
|
+
candidates,
|
|
17311
|
+
secrets,
|
|
17312
|
+
entryPrior,
|
|
17313
|
+
// Degrading is only sound when the disk entry is the pre-call
|
|
17314
|
+
// state this attempt's priors pair with; on a retry it may be an
|
|
17315
|
+
// earlier attempt's committed residue, so escalate into the
|
|
17316
|
+
// reconciling exit instead.
|
|
17317
|
+
attempt === 0
|
|
17318
|
+
);
|
|
17319
|
+
if (!persisted) {
|
|
17320
|
+
revertEntryToDisk(merged.servers, disk?.servers, url);
|
|
17321
|
+
continue;
|
|
17322
|
+
}
|
|
17323
|
+
for (const field of candidates) {
|
|
17324
|
+
attemptWrites.set(priorKey({ serverId, field }), {
|
|
17325
|
+
serverId,
|
|
17326
|
+
field,
|
|
17327
|
+
value: secrets[field] ?? null
|
|
17328
|
+
});
|
|
17329
|
+
}
|
|
17330
|
+
}
|
|
17331
|
+
for (const issuer of effective.idpSessions ?? []) {
|
|
17332
|
+
const serverId = oauthIdpSecretServerId(issuer);
|
|
17333
|
+
const next = getOwnEntry(snapshot.idpSessions, issuer);
|
|
17334
|
+
const entryPrior = await snapshotSecretFields(secretStore, serverId, [
|
|
17335
|
+
IDP_SESSION_FIELD
|
|
17336
|
+
]);
|
|
17337
|
+
priorSecrets.push(...entryPrior);
|
|
17338
|
+
if (next === void 0) {
|
|
17339
|
+
ourWrites.set(
|
|
17340
|
+
priorKey({ serverId, field: IDP_SESSION_FIELD }),
|
|
17341
|
+
null
|
|
17342
|
+
);
|
|
17343
|
+
await secretStore.deleteAllForServer(serverId);
|
|
17344
|
+
attemptWrites.set(
|
|
17345
|
+
priorKey({ serverId, field: IDP_SESSION_FIELD }),
|
|
17346
|
+
{
|
|
17347
|
+
serverId,
|
|
17348
|
+
field: IDP_SESSION_FIELD,
|
|
17349
|
+
value: null
|
|
17350
|
+
}
|
|
17351
|
+
);
|
|
17352
|
+
continue;
|
|
17353
|
+
}
|
|
17354
|
+
const { residue, secrets } = splitIdpSession(next, policy);
|
|
17355
|
+
ourWrites.set(
|
|
17356
|
+
priorKey({ serverId, field: IDP_SESSION_FIELD }),
|
|
17357
|
+
secrets[IDP_SESSION_FIELD] ?? null
|
|
17358
|
+
);
|
|
17359
|
+
setOwnEntry(merged.idpSessions, issuer, residue);
|
|
17360
|
+
if (!durable) {
|
|
17361
|
+
const diskSession = getOwnEntry(disk?.idpSessions, issuer);
|
|
17362
|
+
const keep = preserveNonDurableSecrets(
|
|
17363
|
+
diskSession ? splitIdpSession(diskSession, policy).secrets : {},
|
|
17364
|
+
secrets
|
|
17365
|
+
);
|
|
17366
|
+
if (Object.keys(keep).length > 0) {
|
|
17367
|
+
setOwnEntry(
|
|
17368
|
+
merged.idpSessions,
|
|
17369
|
+
issuer,
|
|
17370
|
+
joinIdpSession(residue, keep)
|
|
17371
|
+
);
|
|
17372
|
+
}
|
|
17373
|
+
}
|
|
17374
|
+
const persisted = await persistEntrySecrets(
|
|
17375
|
+
secretStore,
|
|
17376
|
+
serverId,
|
|
17377
|
+
[IDP_SESSION_FIELD],
|
|
17378
|
+
secrets,
|
|
17379
|
+
entryPrior,
|
|
17380
|
+
// Same as the server loop: degrade on the first attempt only.
|
|
17381
|
+
attempt === 0
|
|
17382
|
+
);
|
|
17383
|
+
if (!persisted) {
|
|
17384
|
+
revertEntryToDisk(merged.idpSessions, disk?.idpSessions, issuer);
|
|
17385
|
+
continue;
|
|
17386
|
+
}
|
|
17387
|
+
attemptWrites.set(priorKey({ serverId, field: IDP_SESSION_FIELD }), {
|
|
17388
|
+
serverId,
|
|
17389
|
+
field: IDP_SESSION_FIELD,
|
|
17390
|
+
value: secrets[IDP_SESSION_FIELD] ?? null
|
|
17391
|
+
});
|
|
17392
|
+
}
|
|
17393
|
+
written = serializeOAuthPersistBlob(merged);
|
|
17394
|
+
await writeStoreFile(filePath, written);
|
|
17395
|
+
unconfirmed = { written, writes: attemptWrites };
|
|
17396
|
+
} catch (error) {
|
|
17397
|
+
foldPriors(priorSecrets);
|
|
17398
|
+
if (await reconcileFailure()) return;
|
|
17399
|
+
throw error;
|
|
17400
|
+
}
|
|
17401
|
+
foldPriors(priorSecrets);
|
|
17402
|
+
let observed;
|
|
17403
|
+
try {
|
|
17404
|
+
observed = await readStoreFile(filePath);
|
|
17405
|
+
} catch {
|
|
17406
|
+
continue;
|
|
17407
|
+
}
|
|
17408
|
+
if (observed === written) return;
|
|
17409
|
+
unconfirmed = null;
|
|
17410
|
+
}
|
|
17411
|
+
if (await reconcileFailure()) return;
|
|
17412
|
+
throw new SecretStoreUnavailableError(
|
|
17413
|
+
`Could not save OAuth state: another process kept overwriting ${filePath} (gave up after ${MAX_WRITE_ATTEMPTS} attempts). Re-run the action to retry.`
|
|
17414
|
+
);
|
|
17415
|
+
});
|
|
17416
|
+
}
|
|
17417
|
+
function secretRequestsFor(snapshot) {
|
|
17418
|
+
const requests = [];
|
|
17419
|
+
for (const [url, state] of Object.entries(snapshot.servers)) {
|
|
17420
|
+
requests.push({
|
|
17421
|
+
serverId: oauthSecretServerId(url),
|
|
17422
|
+
fields: serverSecretFields(state)
|
|
17423
|
+
});
|
|
17424
|
+
}
|
|
17425
|
+
for (const issuer of Object.keys(snapshot.idpSessions)) {
|
|
17426
|
+
requests.push({
|
|
17427
|
+
serverId: oauthIdpSecretServerId(issuer),
|
|
17428
|
+
fields: [IDP_SESSION_FIELD]
|
|
17429
|
+
});
|
|
17430
|
+
}
|
|
17431
|
+
return requests;
|
|
17432
|
+
}
|
|
17433
|
+
async function joinSnapshot(snapshot, secretStore) {
|
|
17434
|
+
const requests = secretRequestsFor(snapshot);
|
|
17435
|
+
const values = requests.length > 0 ? await secretStoreGetManyStrict(secretStore, requests) : {};
|
|
17436
|
+
return {
|
|
17437
|
+
servers: Object.fromEntries(
|
|
17438
|
+
Object.entries(snapshot.servers).map(([url, state]) => [
|
|
17439
|
+
url,
|
|
17440
|
+
joinServerOAuthState(state, values[oauthSecretServerId(url)] ?? {})
|
|
17441
|
+
])
|
|
17442
|
+
),
|
|
17443
|
+
idpSessions: Object.fromEntries(
|
|
17444
|
+
Object.entries(snapshot.idpSessions).map(([issuer, session]) => [
|
|
17445
|
+
issuer,
|
|
17446
|
+
joinIdpSession(session, values[oauthIdpSecretServerId(issuer)] ?? {})
|
|
17447
|
+
])
|
|
17448
|
+
)
|
|
17449
|
+
};
|
|
17450
|
+
}
|
|
17451
|
+
async function migratePlaintextSecrets(filePath, secretStore) {
|
|
17452
|
+
const raw = await readStoreFile(filePath);
|
|
17453
|
+
const fresh = parseOAuthPersistBlob(raw);
|
|
17454
|
+
if (!fresh || !snapshotHasPlaintextSecrets(fresh)) return;
|
|
17455
|
+
const migrateEntrySecrets = async (serverId, secrets) => {
|
|
17456
|
+
const absent = {};
|
|
17457
|
+
for (const [field, value] of Object.entries(secrets)) {
|
|
17458
|
+
const existing = await secretStoreGetStrict(secretStore, serverId, field);
|
|
17459
|
+
if (existing === null || !isUsableStoredSecret(field, existing)) {
|
|
17460
|
+
absent[field] = value;
|
|
17461
|
+
}
|
|
17462
|
+
}
|
|
17463
|
+
if (Object.keys(absent).length > 0) {
|
|
17464
|
+
await secretStoreSetMany(secretStore, serverId, absent);
|
|
17465
|
+
}
|
|
17466
|
+
};
|
|
17467
|
+
const residue = { servers: {}, idpSessions: {} };
|
|
17468
|
+
for (const [url, state] of Object.entries(fresh.servers)) {
|
|
17469
|
+
const split = splitServerOAuthState(state, "all");
|
|
17470
|
+
setOwnEntry(residue.servers, url, split.residue);
|
|
17471
|
+
await migrateEntrySecrets(oauthSecretServerId(url), split.secrets);
|
|
17472
|
+
}
|
|
17473
|
+
for (const [issuer, session] of Object.entries(fresh.idpSessions)) {
|
|
17474
|
+
const split = splitIdpSession(session, "all");
|
|
17475
|
+
setOwnEntry(residue.idpSessions, issuer, split.residue);
|
|
17476
|
+
await migrateEntrySecrets(oauthIdpSecretServerId(issuer), split.secrets);
|
|
17477
|
+
}
|
|
17478
|
+
const stripped = serializeOAuthPersistBlob(residue);
|
|
17479
|
+
if (stripped !== raw) {
|
|
17480
|
+
await writeStoreFile(filePath, stripped);
|
|
17481
|
+
}
|
|
17482
|
+
}
|
|
17483
|
+
async function readOAuthStore(filePath, secretStore = defaultSecretStore()) {
|
|
17484
|
+
return withOAuthStateLock(filePath, "read", async () => {
|
|
17485
|
+
let snapshot = parseOAuthPersistBlob(await readStoreFile(filePath));
|
|
17486
|
+
if (snapshot === null) return null;
|
|
17487
|
+
if (snapshotHasPlaintextSecrets(snapshot) && await secretStoreIsDurable(secretStore)) {
|
|
17488
|
+
try {
|
|
17489
|
+
await migratePlaintextSecrets(filePath, secretStore);
|
|
17490
|
+
snapshot = parseOAuthPersistBlob(await readStoreFile(filePath)) ?? snapshot;
|
|
17491
|
+
} catch (error) {
|
|
17492
|
+
warnMigrationFailure(error);
|
|
17493
|
+
}
|
|
17494
|
+
}
|
|
17495
|
+
return joinSnapshot(snapshot, secretStore);
|
|
17496
|
+
});
|
|
17497
|
+
}
|
|
17498
|
+
async function removeOAuthStore(filePath, secretStore = defaultSecretStore()) {
|
|
17499
|
+
await withOAuthStateLock(filePath, "remove", async () => {
|
|
17500
|
+
const snapshot = await readDiskForMutation(filePath, "remove");
|
|
17501
|
+
if (snapshot) {
|
|
17502
|
+
const targets = [
|
|
17503
|
+
...Object.entries(snapshot.servers).map(([url, state]) => ({
|
|
17504
|
+
id: oauthSecretServerId(url),
|
|
17505
|
+
fields: serverSecretFields(state)
|
|
17506
|
+
})),
|
|
17507
|
+
...Object.keys(snapshot.idpSessions).map((issuer) => ({
|
|
17508
|
+
id: oauthIdpSecretServerId(issuer),
|
|
17509
|
+
fields: [IDP_SESSION_FIELD]
|
|
17510
|
+
}))
|
|
17511
|
+
];
|
|
17512
|
+
const priorSecrets = [];
|
|
17513
|
+
try {
|
|
17514
|
+
for (const { id, fields } of targets) {
|
|
17515
|
+
priorSecrets.push(
|
|
17516
|
+
...await snapshotSecretFields(secretStore, id, fields)
|
|
17517
|
+
);
|
|
17518
|
+
await secretStore.deleteAllForServer(id);
|
|
17519
|
+
}
|
|
17520
|
+
await deleteStoreFile(filePath);
|
|
17521
|
+
} catch (error) {
|
|
17522
|
+
await restoreSecretFields(
|
|
17523
|
+
secretStore,
|
|
17524
|
+
priorSecrets,
|
|
17525
|
+
warnRestoreFailure
|
|
17526
|
+
);
|
|
17527
|
+
throw error;
|
|
17528
|
+
}
|
|
17529
|
+
} else {
|
|
17530
|
+
await deleteStoreFile(filePath);
|
|
17531
|
+
}
|
|
17532
|
+
});
|
|
17533
|
+
}
|
|
17534
|
+
function createFileOAuthPersistBackend(options) {
|
|
17535
|
+
const secretStore = options.secretStore ?? defaultSecretStore();
|
|
17536
|
+
return {
|
|
17537
|
+
async read() {
|
|
17538
|
+
return readOAuthStore(options.filePath, secretStore);
|
|
17539
|
+
},
|
|
17540
|
+
async write(snapshot, sections) {
|
|
17541
|
+
await writeOAuthSections(
|
|
17542
|
+
options.filePath,
|
|
17543
|
+
snapshot,
|
|
17544
|
+
sections,
|
|
17545
|
+
secretStore
|
|
17546
|
+
);
|
|
17547
|
+
},
|
|
17548
|
+
async remove() {
|
|
17549
|
+
await removeOAuthStore(options.filePath, secretStore);
|
|
17550
|
+
}
|
|
17551
|
+
};
|
|
17552
|
+
}
|
|
17553
|
+
|
|
17554
|
+
// ../../core/auth/node/storage-node.ts
|
|
17555
|
+
var DEFAULT_STATE_PATH = getStoreFilePath(getDefaultStorageDir(), "oauth");
|
|
17556
|
+
function getStateFilePath(customPath) {
|
|
17557
|
+
if (customPath) return customPath;
|
|
17558
|
+
if (process.env.MCP_INSPECTOR_OAUTH_STATE_PATH) {
|
|
17559
|
+
return process.env.MCP_INSPECTOR_OAUTH_STATE_PATH;
|
|
17560
|
+
}
|
|
17561
|
+
if (process.env.MCP_STORAGE_DIR) {
|
|
17562
|
+
return getStoreFilePath(process.env.MCP_STORAGE_DIR, "oauth");
|
|
17563
|
+
}
|
|
17564
|
+
return DEFAULT_STATE_PATH;
|
|
17565
|
+
}
|
|
17566
|
+
var sharedStateCache = /* @__PURE__ */ new Map();
|
|
17567
|
+
function getSharedState(stateFilePath) {
|
|
17568
|
+
const key = getStateFilePath(stateFilePath);
|
|
17569
|
+
let shared = sharedStateCache.get(key);
|
|
17570
|
+
if (!shared) {
|
|
17571
|
+
shared = {
|
|
17572
|
+
memory: new OAuthMemoryStore(),
|
|
17573
|
+
coordination: new OAuthStorageCoordination()
|
|
17574
|
+
};
|
|
17575
|
+
sharedStateCache.set(key, shared);
|
|
17576
|
+
}
|
|
17577
|
+
return shared;
|
|
17578
|
+
}
|
|
17579
|
+
var NodeOAuthStorage = class extends OAuthStorageBase {
|
|
17580
|
+
/**
|
|
17581
|
+
* @param storagePath - Optional path to state file. Default: ~/.mcp-inspector/storage/oauth.json
|
|
17582
|
+
* @param secretStore - Optional secret store for tokens/client secrets.
|
|
17583
|
+
* Default: the process-wide selected store. Tests inject an in-memory
|
|
17584
|
+
* double here so they never touch the OS keychain.
|
|
17585
|
+
*/
|
|
17586
|
+
constructor(storagePath, secretStore) {
|
|
17587
|
+
const filePath = getStateFilePath(storagePath);
|
|
17588
|
+
const shared = getSharedState(storagePath);
|
|
17589
|
+
super(
|
|
17590
|
+
shared.memory,
|
|
17591
|
+
createFileOAuthPersistBackend({ filePath, secretStore }),
|
|
17592
|
+
shared.coordination
|
|
17593
|
+
);
|
|
17594
|
+
}
|
|
17595
|
+
};
|
|
17596
|
+
|
|
17597
|
+
// ../../core/auth/node/oauth-callback-server.ts
|
|
17598
|
+
import { createServer } from "http";
|
|
17599
|
+
var DEFAULT_HOSTNAME = "127.0.0.1";
|
|
17600
|
+
var DEFAULT_CALLBACK_PATH = "/oauth/callback";
|
|
17601
|
+
var SUCCESS_HTML = `<!DOCTYPE html>
|
|
17602
|
+
<html>
|
|
17603
|
+
<head><meta charset="utf-8"><title>OAuth complete</title></head>
|
|
17604
|
+
<body><p>OAuth complete. You can close this window.</p></body>
|
|
17605
|
+
</html>`;
|
|
17606
|
+
function errorHtml(message) {
|
|
17607
|
+
return `<!DOCTYPE html>
|
|
17608
|
+
<html>
|
|
17609
|
+
<head><meta charset="utf-8"><title>OAuth error</title></head>
|
|
17610
|
+
<body><p>OAuth failed: ${escapeHtml(message)}</p></body>
|
|
17611
|
+
</html>`;
|
|
17612
|
+
}
|
|
17613
|
+
function escapeHtml(s) {
|
|
17614
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
17615
|
+
}
|
|
17616
|
+
var OAuthCallbackServer = class {
|
|
17617
|
+
server = null;
|
|
17618
|
+
port = 0;
|
|
17619
|
+
callbackPath = DEFAULT_CALLBACK_PATH;
|
|
17620
|
+
handled = false;
|
|
17621
|
+
onCallback;
|
|
17622
|
+
onError;
|
|
17623
|
+
/**
|
|
17624
|
+
* Start the server. Port defaults to 0 (random) when omitted; TUI/CLI callers
|
|
17625
|
+
* pass the resolved port from {@link parseRunnerOAuthCallbackUrl} (6276 by default).
|
|
17626
|
+
* Returns port and redirectUrl for use as oauth.redirectUrl.
|
|
17627
|
+
*/
|
|
17628
|
+
async start(options = {}) {
|
|
16563
17629
|
const {
|
|
16564
17630
|
port = 0,
|
|
16565
17631
|
hostname = DEFAULT_HOSTNAME,
|
|
@@ -18458,7 +19524,11 @@ async function verifySkills(client, entries, metadata) {
|
|
|
18458
19524
|
files,
|
|
18459
19525
|
...incomplete ? { incomplete } : {},
|
|
18460
19526
|
ok: !hasError && !fileFailed,
|
|
18461
|
-
|
|
19527
|
+
// Precedence runs from the loudest verdict down: a broken MUST outranks
|
|
19528
|
+
// an unfinished walk, and an unfinished walk outranks a skill that had
|
|
19529
|
+
// nothing to hash — a `"dynamic"` skill past the run's catalog budget
|
|
19530
|
+
// was not read at all, which `incomplete` already says more precisely.
|
|
19531
|
+
outcome: hasError || fileFailed ? "failed" : incomplete !== void 0 ? "incomplete" : entry.resources === DYNAMIC_RESOURCES ? "unverifiable" : "verified"
|
|
18462
19532
|
});
|
|
18463
19533
|
}
|
|
18464
19534
|
return reports;
|
|
@@ -18490,6 +19560,7 @@ var FILE_COLOR = {
|
|
|
18490
19560
|
};
|
|
18491
19561
|
var VERIFY_STATUS = {
|
|
18492
19562
|
verified: "[Verified \u2014 Enter to re-verify]",
|
|
19563
|
+
unverifiable: "[UNVERIFIABLE \u2014 Enter to re-verify]",
|
|
18493
19564
|
incomplete: "[Verification INCOMPLETE \u2014 Enter to re-verify]",
|
|
18494
19565
|
failed: "[Verification FAILED \u2014 Enter to re-verify]"
|
|
18495
19566
|
};
|
|
@@ -19573,8 +20644,64 @@ function HistoryTab({
|
|
|
19573
20644
|
|
|
19574
20645
|
// src/components/RequestsTab.tsx
|
|
19575
20646
|
import React9, { useEffect as useEffect10, useRef as useRef12 } from "react";
|
|
19576
|
-
import { Box as
|
|
20647
|
+
import { Box as Box13, Text as Text12, useInput as useInput9 } from "ink";
|
|
20648
|
+
|
|
20649
|
+
// src/components/BodyLines.tsx
|
|
20650
|
+
import { Box as Box12, Text as Text11 } from "ink";
|
|
20651
|
+
|
|
20652
|
+
// src/utils/bodyLines.ts
|
|
20653
|
+
var MAX_BODY_LINES = 500;
|
|
20654
|
+
var MAX_BODY_LINE_CHARS = 2e3;
|
|
20655
|
+
function formatBody(body) {
|
|
20656
|
+
try {
|
|
20657
|
+
return JSON.stringify(JSON.parse(body), null, 2);
|
|
20658
|
+
} catch {
|
|
20659
|
+
return body;
|
|
20660
|
+
}
|
|
20661
|
+
}
|
|
20662
|
+
function clipLine(line, maxChars) {
|
|
20663
|
+
if (line.length <= maxChars) return line;
|
|
20664
|
+
return `${line.slice(0, maxChars)}\u2026 (+${line.length - maxChars} chars)`;
|
|
20665
|
+
}
|
|
20666
|
+
function layoutBody(body, maxLines = MAX_BODY_LINES, maxLineChars = MAX_BODY_LINE_CHARS) {
|
|
20667
|
+
const all = formatBody(body).split("\n");
|
|
20668
|
+
return {
|
|
20669
|
+
lines: all.slice(0, maxLines).map((line) => clipLine(line, maxLineChars)),
|
|
20670
|
+
hiddenLines: Math.max(all.length - maxLines, 0),
|
|
20671
|
+
totalLines: all.length
|
|
20672
|
+
};
|
|
20673
|
+
}
|
|
20674
|
+
|
|
20675
|
+
// src/components/BodyLines.tsx
|
|
19577
20676
|
import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
20677
|
+
function BodyLines({
|
|
20678
|
+
body,
|
|
20679
|
+
keyPrefix
|
|
20680
|
+
}) {
|
|
20681
|
+
const { lines, hiddenLines, totalLines } = layoutBody(body);
|
|
20682
|
+
return /* @__PURE__ */ jsxs11(Fragment8, { children: [
|
|
20683
|
+
lines.map((line, idx) => /* @__PURE__ */ jsx12(
|
|
20684
|
+
Box12,
|
|
20685
|
+
{
|
|
20686
|
+
marginTop: idx === 0 ? 1 : 0,
|
|
20687
|
+
paddingLeft: 2,
|
|
20688
|
+
flexShrink: 0,
|
|
20689
|
+
children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: line })
|
|
20690
|
+
},
|
|
20691
|
+
`${keyPrefix}-${idx}`
|
|
20692
|
+
)),
|
|
20693
|
+
hiddenLines > 0 && /* @__PURE__ */ jsx12(Box12, { paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Text11, { dimColor: true, italic: true, children: [
|
|
20694
|
+
"\u2026 ",
|
|
20695
|
+
hiddenLines,
|
|
20696
|
+
" more lines not shown (",
|
|
20697
|
+
totalLines,
|
|
20698
|
+
" total)"
|
|
20699
|
+
] }) })
|
|
20700
|
+
] });
|
|
20701
|
+
}
|
|
20702
|
+
|
|
20703
|
+
// src/components/RequestsTab.tsx
|
|
20704
|
+
import { Fragment as Fragment9, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
19578
20705
|
function RequestsTab({
|
|
19579
20706
|
requests,
|
|
19580
20707
|
width,
|
|
@@ -19642,9 +20769,9 @@ function RequestsTab({
|
|
|
19642
20769
|
if (status >= 400) return "red";
|
|
19643
20770
|
return "gray";
|
|
19644
20771
|
};
|
|
19645
|
-
return /* @__PURE__ */
|
|
19646
|
-
/* @__PURE__ */
|
|
19647
|
-
|
|
20772
|
+
return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "row", width, height, children: [
|
|
20773
|
+
/* @__PURE__ */ jsxs12(
|
|
20774
|
+
Box13,
|
|
19648
20775
|
{
|
|
19649
20776
|
width: listWidth,
|
|
19650
20777
|
height,
|
|
@@ -19656,8 +20783,8 @@ function RequestsTab({
|
|
|
19656
20783
|
flexDirection: "column",
|
|
19657
20784
|
paddingX: 1,
|
|
19658
20785
|
children: [
|
|
19659
|
-
/* @__PURE__ */
|
|
19660
|
-
|
|
20786
|
+
/* @__PURE__ */ jsx13(Box13, { paddingY: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs12(
|
|
20787
|
+
Text12,
|
|
19661
20788
|
{
|
|
19662
20789
|
bold: true,
|
|
19663
20790
|
backgroundColor: focusedPane === "requests" ? "yellow" : void 0,
|
|
@@ -19668,8 +20795,8 @@ function RequestsTab({
|
|
|
19668
20795
|
]
|
|
19669
20796
|
}
|
|
19670
20797
|
) }),
|
|
19671
|
-
requests.length === 0 ? /* @__PURE__ */
|
|
19672
|
-
|
|
20798
|
+
requests.length === 0 ? /* @__PURE__ */ jsx13(Box13, { paddingY: 1, children: /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "No requests" }) }) : /* @__PURE__ */ jsx13(
|
|
20799
|
+
Box13,
|
|
19673
20800
|
{
|
|
19674
20801
|
flexDirection: "column",
|
|
19675
20802
|
height: visibleCount,
|
|
@@ -19682,14 +20809,14 @@ function RequestsTab({
|
|
|
19682
20809
|
const statusText = req.responseStatus ? `${req.responseStatus}` : req.error ? "ERROR" : "...";
|
|
19683
20810
|
const categoryLabel = req.category === "auth" ? "AUTH" : "MCP ";
|
|
19684
20811
|
const methodPadded = req.method === "GET" ? "GET " : req.method;
|
|
19685
|
-
return /* @__PURE__ */
|
|
20812
|
+
return /* @__PURE__ */ jsx13(Box13, { paddingY: 0, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { color: isSelected ? "white" : "white", children: [
|
|
19686
20813
|
isSelected ? "\u25B6 " : " ",
|
|
19687
|
-
/* @__PURE__ */
|
|
20814
|
+
/* @__PURE__ */ jsx13(Text12, { children: categoryLabel }),
|
|
19688
20815
|
" ",
|
|
19689
|
-
/* @__PURE__ */
|
|
20816
|
+
/* @__PURE__ */ jsx13(Text12, { color: statusColor, children: methodPadded }),
|
|
19690
20817
|
" ",
|
|
19691
|
-
/* @__PURE__ */
|
|
19692
|
-
req.duration !== void 0 && /* @__PURE__ */
|
|
20818
|
+
/* @__PURE__ */ jsx13(Text12, { dimColor: true, children: statusText }),
|
|
20819
|
+
req.duration !== void 0 && /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
19693
20820
|
" ",
|
|
19694
20821
|
req.duration,
|
|
19695
20822
|
"ms"
|
|
@@ -19701,8 +20828,8 @@ function RequestsTab({
|
|
|
19701
20828
|
]
|
|
19702
20829
|
}
|
|
19703
20830
|
),
|
|
19704
|
-
/* @__PURE__ */
|
|
19705
|
-
|
|
20831
|
+
/* @__PURE__ */ jsx13(
|
|
20832
|
+
Box13,
|
|
19706
20833
|
{
|
|
19707
20834
|
width: detailWidth,
|
|
19708
20835
|
height,
|
|
@@ -19714,9 +20841,9 @@ function RequestsTab({
|
|
|
19714
20841
|
borderBottom: false,
|
|
19715
20842
|
borderLeft: false,
|
|
19716
20843
|
borderRight: false,
|
|
19717
|
-
children: selectedRequest ? /* @__PURE__ */
|
|
19718
|
-
/* @__PURE__ */
|
|
19719
|
-
|
|
20844
|
+
children: selectedRequest ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
20845
|
+
/* @__PURE__ */ jsx13(Box13, { flexShrink: 0, paddingTop: 1, children: /* @__PURE__ */ jsxs12(
|
|
20846
|
+
Text12,
|
|
19720
20847
|
{
|
|
19721
20848
|
bold: true,
|
|
19722
20849
|
backgroundColor: focusedPane === "details" ? "yellow" : void 0,
|
|
@@ -19728,17 +20855,17 @@ function RequestsTab({
|
|
|
19728
20855
|
]
|
|
19729
20856
|
}
|
|
19730
20857
|
) }),
|
|
19731
|
-
/* @__PURE__ */
|
|
19732
|
-
/* @__PURE__ */
|
|
20858
|
+
/* @__PURE__ */ jsxs12(ScrollView, { ref: scrollViewRef, height: height - 5, children: [
|
|
20859
|
+
/* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { bold: true, children: [
|
|
19733
20860
|
"Category:",
|
|
19734
20861
|
" ",
|
|
19735
|
-
/* @__PURE__ */
|
|
20862
|
+
/* @__PURE__ */ jsx13(Text12, { children: selectedRequest.category === "auth" ? "auth" : "transport" })
|
|
19736
20863
|
] }) }),
|
|
19737
|
-
selectedRequest.responseStatus !== void 0 ? /* @__PURE__ */
|
|
20864
|
+
selectedRequest.responseStatus !== void 0 ? /* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { bold: true, children: [
|
|
19738
20865
|
"Status:",
|
|
19739
20866
|
" ",
|
|
19740
|
-
/* @__PURE__ */
|
|
19741
|
-
|
|
20867
|
+
/* @__PURE__ */ jsxs12(
|
|
20868
|
+
Text12,
|
|
19742
20869
|
{
|
|
19743
20870
|
color: getStatusColor(selectedRequest.responseStatus),
|
|
19744
20871
|
children: [
|
|
@@ -19748,54 +20875,44 @@ function RequestsTab({
|
|
|
19748
20875
|
]
|
|
19749
20876
|
}
|
|
19750
20877
|
)
|
|
19751
|
-
] }) }) : selectedRequest.error ? /* @__PURE__ */
|
|
20878
|
+
] }) }) : selectedRequest.error ? /* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { bold: true, color: "red", children: [
|
|
19752
20879
|
"Error: ",
|
|
19753
20880
|
selectedRequest.error
|
|
19754
|
-
] }) }) : /* @__PURE__ */
|
|
19755
|
-
selectedRequest.duration !== void 0 && /* @__PURE__ */
|
|
20881
|
+
] }) }) : /* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text12, { dimColor: true, italic: true, children: "Request in progress..." }) }),
|
|
20882
|
+
selectedRequest.duration !== void 0 && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
19756
20883
|
selectedRequest.timestamp.toLocaleTimeString(),
|
|
19757
20884
|
" (",
|
|
19758
20885
|
selectedRequest.duration,
|
|
19759
20886
|
"ms)"
|
|
19760
20887
|
] }) }),
|
|
19761
|
-
/* @__PURE__ */
|
|
20888
|
+
/* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text12, { bold: true, children: "Request Headers:" }) }),
|
|
19762
20889
|
Object.entries(selectedRequest.requestHeaders).map(
|
|
19763
|
-
([key, value]) => /* @__PURE__ */
|
|
20890
|
+
([key, value]) => /* @__PURE__ */ jsx13(Box13, { marginTop: 0, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
19764
20891
|
key,
|
|
19765
20892
|
": ",
|
|
19766
20893
|
value
|
|
19767
20894
|
] }) }, key)
|
|
19768
20895
|
),
|
|
19769
|
-
selectedRequest.requestBody && /* @__PURE__ */
|
|
19770
|
-
/* @__PURE__ */
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
{
|
|
19777
|
-
marginTop: idx === 0 ? 1 : 0,
|
|
19778
|
-
paddingLeft: 2,
|
|
19779
|
-
flexShrink: 0,
|
|
19780
|
-
children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: line })
|
|
19781
|
-
},
|
|
19782
|
-
`req-body-${idx}`
|
|
19783
|
-
));
|
|
19784
|
-
} catch {
|
|
19785
|
-
return /* @__PURE__ */ jsx12(Box12, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: selectedRequest.requestBody }) });
|
|
20896
|
+
selectedRequest.requestBody && /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
20897
|
+
/* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text12, { bold: true, children: "Request Body:" }) }),
|
|
20898
|
+
/* @__PURE__ */ jsx13(
|
|
20899
|
+
BodyLines,
|
|
20900
|
+
{
|
|
20901
|
+
body: selectedRequest.requestBody,
|
|
20902
|
+
keyPrefix: "req-body"
|
|
19786
20903
|
}
|
|
19787
|
-
|
|
20904
|
+
)
|
|
19788
20905
|
] }),
|
|
19789
|
-
selectedRequest.responseHeaders && Object.keys(selectedRequest.responseHeaders).length > 0 && /* @__PURE__ */
|
|
19790
|
-
/* @__PURE__ */
|
|
20906
|
+
selectedRequest.responseHeaders && Object.keys(selectedRequest.responseHeaders).length > 0 && /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
20907
|
+
/* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text12, { bold: true, children: "Response Headers:" }) }),
|
|
19791
20908
|
Object.entries(selectedRequest.responseHeaders).map(
|
|
19792
|
-
([key, value]) => /* @__PURE__ */
|
|
19793
|
-
|
|
20909
|
+
([key, value]) => /* @__PURE__ */ jsx13(
|
|
20910
|
+
Box13,
|
|
19794
20911
|
{
|
|
19795
20912
|
marginTop: 0,
|
|
19796
20913
|
paddingLeft: 2,
|
|
19797
20914
|
flexShrink: 0,
|
|
19798
|
-
children: /* @__PURE__ */
|
|
20915
|
+
children: /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
19799
20916
|
key,
|
|
19800
20917
|
": ",
|
|
19801
20918
|
value
|
|
@@ -19805,38 +20922,28 @@ function RequestsTab({
|
|
|
19805
20922
|
)
|
|
19806
20923
|
)
|
|
19807
20924
|
] }),
|
|
19808
|
-
selectedRequest.responseBody && /* @__PURE__ */
|
|
19809
|
-
/* @__PURE__ */
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
{
|
|
19816
|
-
marginTop: idx === 0 ? 1 : 0,
|
|
19817
|
-
paddingLeft: 2,
|
|
19818
|
-
flexShrink: 0,
|
|
19819
|
-
children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: line })
|
|
19820
|
-
},
|
|
19821
|
-
`resp-body-${idx}`
|
|
19822
|
-
));
|
|
19823
|
-
} catch {
|
|
19824
|
-
return /* @__PURE__ */ jsx12(Box12, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: selectedRequest.responseBody }) });
|
|
20925
|
+
selectedRequest.responseBody && /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
20926
|
+
/* @__PURE__ */ jsx13(Box13, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text12, { bold: true, children: "Response Body:" }) }),
|
|
20927
|
+
/* @__PURE__ */ jsx13(
|
|
20928
|
+
BodyLines,
|
|
20929
|
+
{
|
|
20930
|
+
body: selectedRequest.responseBody,
|
|
20931
|
+
keyPrefix: "resp-body"
|
|
19825
20932
|
}
|
|
19826
|
-
|
|
20933
|
+
)
|
|
19827
20934
|
] })
|
|
19828
20935
|
] }),
|
|
19829
|
-
focusedPane === "details" && /* @__PURE__ */
|
|
19830
|
-
|
|
20936
|
+
focusedPane === "details" && /* @__PURE__ */ jsx13(
|
|
20937
|
+
Box13,
|
|
19831
20938
|
{
|
|
19832
20939
|
flexShrink: 0,
|
|
19833
20940
|
height: 1,
|
|
19834
20941
|
justifyContent: "center",
|
|
19835
20942
|
backgroundColor: "gray",
|
|
19836
|
-
children: /* @__PURE__ */
|
|
20943
|
+
children: /* @__PURE__ */ jsx13(Text12, { bold: true, color: "white", children: "\u2191/\u2193 to scroll, + to zoom" })
|
|
19837
20944
|
}
|
|
19838
20945
|
)
|
|
19839
|
-
] }) : /* @__PURE__ */
|
|
20946
|
+
] }) : /* @__PURE__ */ jsx13(Box13, { paddingY: 1, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Select a request to view details" }) })
|
|
19840
20947
|
}
|
|
19841
20948
|
)
|
|
19842
20949
|
] });
|
|
@@ -19844,16 +20951,16 @@ function RequestsTab({
|
|
|
19844
20951
|
|
|
19845
20952
|
// src/components/ToolTestModal.tsx
|
|
19846
20953
|
import React26, { useState as useState14 } from "react";
|
|
19847
|
-
import { Box as
|
|
20954
|
+
import { Box as Box25, Text as Text22, useInput as useInput18 } from "ink";
|
|
19848
20955
|
|
|
19849
20956
|
// node_modules/ink-form/lib/Form.js
|
|
19850
|
-
import { Box as
|
|
20957
|
+
import { Box as Box24, useFocusManager, useInput as useInput17 } from "ink";
|
|
19851
20958
|
import { useEffect as useEffect13, useMemo as useMemo3, useState as useState13 } from "react";
|
|
19852
20959
|
import * as React24 from "react";
|
|
19853
20960
|
|
|
19854
20961
|
// node_modules/ink-form/lib/FormHeader.js
|
|
19855
20962
|
import * as React10 from "react";
|
|
19856
|
-
import { Box as
|
|
20963
|
+
import { Box as Box14, Text as Text13, useInput as useInput10 } from "ink";
|
|
19857
20964
|
var FormHeader = (props) => {
|
|
19858
20965
|
const sections = props.form.sections;
|
|
19859
20966
|
useInput10((input, key) => {
|
|
@@ -19870,42 +20977,42 @@ var FormHeader = (props) => {
|
|
|
19870
20977
|
}
|
|
19871
20978
|
}, { isActive: !props.editingField });
|
|
19872
20979
|
return React10.createElement(
|
|
19873
|
-
|
|
20980
|
+
Box14,
|
|
19874
20981
|
{ borderStyle: "double", width: "100%", flexDirection: "column" },
|
|
19875
20982
|
React10.createElement(
|
|
19876
|
-
|
|
20983
|
+
Box14,
|
|
19877
20984
|
{ width: "100%" },
|
|
19878
20985
|
React10.createElement(
|
|
19879
|
-
|
|
20986
|
+
Box14,
|
|
19880
20987
|
{ flexGrow: 1 },
|
|
19881
|
-
React10.createElement(
|
|
20988
|
+
React10.createElement(Text13, { bold: true }, props.form.title)
|
|
19882
20989
|
),
|
|
19883
20990
|
React10.createElement(
|
|
19884
|
-
|
|
20991
|
+
Box14,
|
|
19885
20992
|
null,
|
|
19886
|
-
React10.createElement(
|
|
20993
|
+
React10.createElement(Text13, null, !props.editingField ? "Use arrow keys to move around" : "Press ESC to cancel, or Enter to complete field")
|
|
19887
20994
|
)
|
|
19888
20995
|
),
|
|
19889
20996
|
React10.createElement(
|
|
19890
|
-
|
|
20997
|
+
Box14,
|
|
19891
20998
|
{ width: "100%" },
|
|
19892
|
-
React10.createElement(
|
|
19893
|
-
|
|
20999
|
+
React10.createElement(Box14, null, !props.editingField ? sections.map((section, id) => React10.createElement(
|
|
21000
|
+
Box14,
|
|
19894
21001
|
{ key: section.title },
|
|
19895
21002
|
React10.createElement(
|
|
19896
|
-
|
|
21003
|
+
Text13,
|
|
19897
21004
|
{ color: "gray" },
|
|
19898
21005
|
"[",
|
|
19899
21006
|
id + 1,
|
|
19900
21007
|
"] "
|
|
19901
21008
|
),
|
|
19902
|
-
React10.createElement(
|
|
19903
|
-
React10.createElement(
|
|
21009
|
+
React10.createElement(Text13, { color: props.currentTab === id ? "blue" : void 0, underline: props.currentTab === id }, section.title),
|
|
21010
|
+
React10.createElement(Text13, null, " ")
|
|
19904
21011
|
)) : React10.createElement(
|
|
19905
|
-
|
|
21012
|
+
Box14,
|
|
19906
21013
|
null,
|
|
19907
21014
|
React10.createElement(
|
|
19908
|
-
|
|
21015
|
+
Text13,
|
|
19909
21016
|
null,
|
|
19910
21017
|
"Editing ",
|
|
19911
21018
|
props.editingField
|
|
@@ -19917,18 +21024,18 @@ var FormHeader = (props) => {
|
|
|
19917
21024
|
|
|
19918
21025
|
// node_modules/ink-form/lib/FormFieldRenderer.js
|
|
19919
21026
|
import React22, { useState as useState12 } from "react";
|
|
19920
|
-
import { Box as
|
|
21027
|
+
import { Box as Box22, useFocus, Text as Text20, useInput as useInput15 } from "ink";
|
|
19921
21028
|
|
|
19922
21029
|
// node_modules/ink-form/lib/managers/FloatFormFieldManager.js
|
|
19923
21030
|
import React13 from "react";
|
|
19924
21031
|
|
|
19925
21032
|
// node_modules/ink-form/lib/NumberFieldRenderer.js
|
|
19926
21033
|
import React12 from "react";
|
|
19927
|
-
import { Box as
|
|
21034
|
+
import { Box as Box15, Text as Text15, useInput as useInput12 } from "ink";
|
|
19928
21035
|
|
|
19929
21036
|
// node_modules/ink-text-input/build/index.js
|
|
19930
21037
|
import React11, { useState as useState10, useEffect as useEffect11 } from "react";
|
|
19931
|
-
import { Text as
|
|
21038
|
+
import { Text as Text14, useInput as useInput11 } from "ink";
|
|
19932
21039
|
|
|
19933
21040
|
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
19934
21041
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
@@ -20510,7 +21617,7 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
|
|
|
20510
21617
|
onChange(nextValue);
|
|
20511
21618
|
}
|
|
20512
21619
|
}, { isActive: focus });
|
|
20513
|
-
return React11.createElement(
|
|
21620
|
+
return React11.createElement(Text14, null, placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue);
|
|
20514
21621
|
}
|
|
20515
21622
|
var build_default = TextInput;
|
|
20516
21623
|
|
|
@@ -20554,10 +21661,10 @@ var NumberFieldRenderer = (props) => {
|
|
|
20554
21661
|
}
|
|
20555
21662
|
});
|
|
20556
21663
|
return React12.createElement(
|
|
20557
|
-
|
|
21664
|
+
Box15,
|
|
20558
21665
|
{ borderStyle: "round", width: "100%", flexDirection: "column" },
|
|
20559
21666
|
React12.createElement(
|
|
20560
|
-
|
|
21667
|
+
Box15,
|
|
20561
21668
|
null,
|
|
20562
21669
|
React12.createElement(build_default, { value: "" + (props.value ?? ""), onChange: (value) => {
|
|
20563
21670
|
if (regex.test(value)) {
|
|
@@ -20570,9 +21677,9 @@ var NumberFieldRenderer = (props) => {
|
|
|
20570
21677
|
}, placeholder: props.field.placeholder, onSubmit: () => props.onSetEditingField(void 0) })
|
|
20571
21678
|
),
|
|
20572
21679
|
React12.createElement(
|
|
20573
|
-
|
|
21680
|
+
Box15,
|
|
20574
21681
|
null,
|
|
20575
|
-
React12.createElement(
|
|
21682
|
+
React12.createElement(Text15, { dimColor: true }, "Press UP/DOWN to increase or decrease the value.")
|
|
20576
21683
|
)
|
|
20577
21684
|
);
|
|
20578
21685
|
};
|
|
@@ -20594,11 +21701,11 @@ var IntegerFormFieldManager = class {
|
|
|
20594
21701
|
|
|
20595
21702
|
// node_modules/ink-form/lib/managers/SelectFormFieldManager.js
|
|
20596
21703
|
import React18 from "react";
|
|
20597
|
-
import { Box as
|
|
21704
|
+
import { Box as Box18 } from "ink";
|
|
20598
21705
|
|
|
20599
21706
|
// node_modules/ink-select-input/build/Indicator.js
|
|
20600
21707
|
import React15 from "react";
|
|
20601
|
-
import { Box as
|
|
21708
|
+
import { Box as Box16, Text as Text16 } from "ink";
|
|
20602
21709
|
|
|
20603
21710
|
// node_modules/is-unicode-supported/index.js
|
|
20604
21711
|
import process3 from "process";
|
|
@@ -20889,15 +21996,15 @@ var replacements = Object.entries(specialMainSymbols);
|
|
|
20889
21996
|
|
|
20890
21997
|
// node_modules/ink-select-input/build/Indicator.js
|
|
20891
21998
|
function Indicator({ isSelected = false }) {
|
|
20892
|
-
return React15.createElement(
|
|
21999
|
+
return React15.createElement(Box16, { marginRight: 1 }, isSelected ? React15.createElement(Text16, { color: "blue" }, figures_default.pointer) : React15.createElement(Text16, null, " "));
|
|
20893
22000
|
}
|
|
20894
22001
|
var Indicator_default = Indicator;
|
|
20895
22002
|
|
|
20896
22003
|
// node_modules/ink-select-input/build/Item.js
|
|
20897
22004
|
import * as React16 from "react";
|
|
20898
|
-
import { Text as
|
|
22005
|
+
import { Text as Text17 } from "ink";
|
|
20899
22006
|
function Item({ isSelected = false, label }) {
|
|
20900
|
-
return React16.createElement(
|
|
22007
|
+
return React16.createElement(Text17, { color: isSelected ? "blue" : void 0 }, label);
|
|
20901
22008
|
}
|
|
20902
22009
|
var Item_default = Item;
|
|
20903
22010
|
|
|
@@ -20928,7 +22035,7 @@ function toRotated(array, steps) {
|
|
|
20928
22035
|
}
|
|
20929
22036
|
|
|
20930
22037
|
// node_modules/ink-select-input/build/SelectInput.js
|
|
20931
|
-
import { Box as
|
|
22038
|
+
import { Box as Box17, useInput as useInput13 } from "ink";
|
|
20932
22039
|
function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicatorComponent = Indicator_default, itemComponent = Item_default, limit: customLimit, onSelect, onHighlight }) {
|
|
20933
22040
|
const hasLimit = typeof customLimit === "number" && items.length > customLimit;
|
|
20934
22041
|
const limit = hasLimit ? Math.min(customLimit, items.length) : items.length;
|
|
@@ -20995,12 +22102,12 @@ function SelectInput({ items = [], isFocused = true, initialIndex = 0, indicator
|
|
|
20995
22102
|
onHighlight
|
|
20996
22103
|
]), { isActive: isFocused });
|
|
20997
22104
|
const slicedItems = hasLimit ? toRotated(items, rotateIndex).slice(0, limit) : items;
|
|
20998
|
-
return React17.createElement(
|
|
22105
|
+
return React17.createElement(Box17, { flexDirection: "column" }, slicedItems.map((item, index) => {
|
|
20999
22106
|
const isSelected = index === selectedIndex;
|
|
21000
22107
|
return (
|
|
21001
22108
|
// @ts-expect-error - `key` can't be optional but `item.value` is generic T
|
|
21002
22109
|
React17.createElement(
|
|
21003
|
-
|
|
22110
|
+
Box17,
|
|
21004
22111
|
{ key: item.key ?? item.value },
|
|
21005
22112
|
React17.createElement(indicatorComponent, { isSelected }),
|
|
21006
22113
|
React17.createElement(itemComponent, { ...item, isSelected })
|
|
@@ -21014,7 +22121,7 @@ var SelectInput_default = SelectInput;
|
|
|
21014
22121
|
var SelectFormFieldManager = class {
|
|
21015
22122
|
type = "select";
|
|
21016
22123
|
renderField = (props) => React18.createElement(
|
|
21017
|
-
|
|
22124
|
+
Box18,
|
|
21018
22125
|
{ borderStyle: "round", width: "100%" },
|
|
21019
22126
|
React18.createElement(SelectInput_default, { items: props.field.options.map((option) => ({ value: option.value, label: option.label ?? option.value })), onHighlight: (option) => props.onChange(option.value), initialIndex: props.field.options.findIndex((option) => option.value === props.value) ?? 0 })
|
|
21020
22127
|
);
|
|
@@ -21023,11 +22130,11 @@ var SelectFormFieldManager = class {
|
|
|
21023
22130
|
|
|
21024
22131
|
// node_modules/ink-form/lib/managers/StringFormFieldManager.js
|
|
21025
22132
|
import React19 from "react";
|
|
21026
|
-
import { Box as
|
|
22133
|
+
import { Box as Box19, Transform } from "ink";
|
|
21027
22134
|
var StringFormFieldManager = class {
|
|
21028
22135
|
type = "string";
|
|
21029
22136
|
renderField = (props) => React19.createElement(
|
|
21030
|
-
|
|
22137
|
+
Box19,
|
|
21031
22138
|
{ borderStyle: "round", width: "100%" },
|
|
21032
22139
|
React19.createElement(build_default, { value: props.value ?? "", onChange: (value) => {
|
|
21033
22140
|
props.onChange(value);
|
|
@@ -21043,7 +22150,7 @@ var StringFormFieldManager = class {
|
|
|
21043
22150
|
|
|
21044
22151
|
// node_modules/ink-form/lib/managers/BooleanFormFieldManager.js
|
|
21045
22152
|
import React20 from "react";
|
|
21046
|
-
import { Box as
|
|
22153
|
+
import { Box as Box20, Text as Text18, useInput as useInput14 } from "ink";
|
|
21047
22154
|
var BooleanFormFieldManager = class {
|
|
21048
22155
|
type = "boolean";
|
|
21049
22156
|
renderField = (props) => {
|
|
@@ -21053,21 +22160,21 @@ var BooleanFormFieldManager = class {
|
|
|
21053
22160
|
}
|
|
21054
22161
|
});
|
|
21055
22162
|
return React20.createElement(
|
|
21056
|
-
|
|
22163
|
+
Box20,
|
|
21057
22164
|
{ width: "100%", borderStyle: "round", borderColor: props.value ? "green" : "gray", marginBottom: 2 },
|
|
21058
22165
|
React20.createElement(
|
|
21059
|
-
|
|
22166
|
+
Box20,
|
|
21060
22167
|
{ marginRight: 2 },
|
|
21061
|
-
React20.createElement(
|
|
22168
|
+
React20.createElement(Text18, { color: props.value ? "green" : "gray" }, props.value === void 0 ? "[Not set]" : props.value ? "[True]" : "[False]")
|
|
21062
22169
|
),
|
|
21063
22170
|
React20.createElement(
|
|
21064
|
-
|
|
22171
|
+
Box20,
|
|
21065
22172
|
{ flexGrow: 1 },
|
|
21066
|
-
React20.createElement(
|
|
22173
|
+
React20.createElement(Text18, null, "Press Space to toggle value")
|
|
21067
22174
|
)
|
|
21068
22175
|
);
|
|
21069
22176
|
};
|
|
21070
|
-
renderValue = (props) => React20.createElement(
|
|
22177
|
+
renderValue = (props) => React20.createElement(Text18, null, props.value === void 0 ? "[Not set]" : props.value ? "[True]" : "[False]");
|
|
21071
22178
|
};
|
|
21072
22179
|
|
|
21073
22180
|
// node_modules/ink-form/lib/managers/managers.js
|
|
@@ -21084,20 +22191,20 @@ var getManager = (formFieldType, customManagers = []) => {
|
|
|
21084
22191
|
|
|
21085
22192
|
// node_modules/ink-form/lib/DescriptionRenderer.js
|
|
21086
22193
|
import React21 from "react";
|
|
21087
|
-
import { Box as
|
|
22194
|
+
import { Box as Box21, Text as Text19 } from "ink";
|
|
21088
22195
|
var DescriptionRenderer = (props) => {
|
|
21089
22196
|
if (!props.description) {
|
|
21090
22197
|
return null;
|
|
21091
22198
|
} else if (props.description.type) {
|
|
21092
22199
|
return props.description;
|
|
21093
22200
|
} else if (Array.isArray(props.description)) {
|
|
21094
|
-
return React21.createElement(
|
|
21095
|
-
|
|
22201
|
+
return React21.createElement(Box21, { flexDirection: "column" }, props.description.map((line) => React21.createElement(
|
|
22202
|
+
Box21,
|
|
21096
22203
|
{ key: line, width: "100%", marginBottom: 1 },
|
|
21097
|
-
React21.createElement(
|
|
22204
|
+
React21.createElement(Text19, null, line)
|
|
21098
22205
|
)));
|
|
21099
22206
|
} else {
|
|
21100
|
-
return React21.createElement(
|
|
22207
|
+
return React21.createElement(Text19, null, props.description);
|
|
21101
22208
|
}
|
|
21102
22209
|
};
|
|
21103
22210
|
|
|
@@ -21140,24 +22247,24 @@ var FormFieldRenderer = (props) => {
|
|
|
21140
22247
|
if (!isEditing) {
|
|
21141
22248
|
const RenderValue = manager?.renderValue ?? (() => React22.createElement(React22.Fragment, null, props.value));
|
|
21142
22249
|
return React22.createElement(
|
|
21143
|
-
|
|
22250
|
+
Box22,
|
|
21144
22251
|
{ marginX: 2, paddingX: 1, borderStyle: "round", borderColor: isFocused ? "blue" : void 0 },
|
|
21145
22252
|
React22.createElement(
|
|
21146
|
-
|
|
22253
|
+
Box22,
|
|
21147
22254
|
{ flexGrow: 1 },
|
|
21148
|
-
React22.createElement(
|
|
21149
|
-
props.field.required && React22.createElement(
|
|
21150
|
-
React22.createElement(
|
|
22255
|
+
React22.createElement(Text20, { underline: isFocused, color: isFocused ? "blue" : void 0 }, props.field.label ?? props.field.name),
|
|
22256
|
+
props.field.required && React22.createElement(Text20, { color: "red" }, "*"),
|
|
22257
|
+
React22.createElement(Text20, null, ": "),
|
|
21151
22258
|
React22.createElement(
|
|
21152
|
-
|
|
22259
|
+
Text20,
|
|
21153
22260
|
{ dimColor: true },
|
|
21154
22261
|
React22.createElement(RenderValue, { value: props.value, field: props.field })
|
|
21155
22262
|
)
|
|
21156
22263
|
),
|
|
21157
22264
|
isFocused && React22.createElement(
|
|
21158
|
-
|
|
22265
|
+
Box22,
|
|
21159
22266
|
null,
|
|
21160
|
-
React22.createElement(
|
|
22267
|
+
React22.createElement(Text20, null, "Press enter to edit")
|
|
21161
22268
|
)
|
|
21162
22269
|
);
|
|
21163
22270
|
} else {
|
|
@@ -21174,7 +22281,7 @@ var FormFieldRenderer = (props) => {
|
|
|
21174
22281
|
};
|
|
21175
22282
|
if (!manager) {
|
|
21176
22283
|
component = React22.createElement(
|
|
21177
|
-
|
|
22284
|
+
Text20,
|
|
21178
22285
|
{ color: "red" },
|
|
21179
22286
|
"No formfield manager for form field of type ",
|
|
21180
22287
|
props.field.type,
|
|
@@ -21185,39 +22292,39 @@ var FormFieldRenderer = (props) => {
|
|
|
21185
22292
|
component = React22.createElement(Field, { ...rendererProps });
|
|
21186
22293
|
}
|
|
21187
22294
|
return React22.createElement(
|
|
21188
|
-
|
|
22295
|
+
Box22,
|
|
21189
22296
|
{ paddingX: 3, paddingY: 1, flexDirection: "column" },
|
|
21190
22297
|
React22.createElement(
|
|
21191
|
-
|
|
22298
|
+
Box22,
|
|
21192
22299
|
null,
|
|
21193
|
-
React22.createElement(
|
|
21194
|
-
props.field.required && React22.createElement(
|
|
21195
|
-
React22.createElement(
|
|
22300
|
+
React22.createElement(Text20, null, props.field.label ?? props.field.name),
|
|
22301
|
+
props.field.required && React22.createElement(Text20, { color: "red" }, "*"),
|
|
22302
|
+
React22.createElement(Text20, null, ": ")
|
|
21196
22303
|
),
|
|
21197
|
-
React22.createElement(
|
|
22304
|
+
React22.createElement(Box22, null, component),
|
|
21198
22305
|
props.field.description && React22.createElement(
|
|
21199
|
-
|
|
22306
|
+
Box22,
|
|
21200
22307
|
null,
|
|
21201
22308
|
React22.createElement(
|
|
21202
|
-
|
|
22309
|
+
Text20,
|
|
21203
22310
|
{ dimColor: true },
|
|
21204
22311
|
React22.createElement(DescriptionRenderer, { description: props.field.description })
|
|
21205
22312
|
)
|
|
21206
22313
|
),
|
|
21207
22314
|
error && React22.createElement(
|
|
21208
|
-
|
|
22315
|
+
Box22,
|
|
21209
22316
|
null,
|
|
21210
22317
|
React22.createElement(
|
|
21211
|
-
|
|
22318
|
+
Text20,
|
|
21212
22319
|
{ color: "red" },
|
|
21213
22320
|
"Error: ",
|
|
21214
22321
|
error
|
|
21215
22322
|
)
|
|
21216
22323
|
),
|
|
21217
22324
|
React22.createElement(
|
|
21218
|
-
|
|
22325
|
+
Box22,
|
|
21219
22326
|
{ marginTop: 2 },
|
|
21220
|
-
React22.createElement(
|
|
22327
|
+
React22.createElement(Text20, { dimColor: true }, error ? React22.createElement(React22.Fragment, null, "Press ESC to cancel.") : React22.createElement(
|
|
21221
22328
|
React22.Fragment,
|
|
21222
22329
|
null,
|
|
21223
22330
|
"Press ",
|
|
@@ -21236,7 +22343,7 @@ var canSubmit = (form, value) => {
|
|
|
21236
22343
|
|
|
21237
22344
|
// node_modules/ink-form/lib/SubmitButton.js
|
|
21238
22345
|
import React23 from "react";
|
|
21239
|
-
import { Text as
|
|
22346
|
+
import { Text as Text21, Box as Box23, useFocus as useFocus2, useInput as useInput16 } from "ink";
|
|
21240
22347
|
var SubmitButton = (props) => {
|
|
21241
22348
|
const { isFocused } = useFocus2({ isActive: props.canSubmit });
|
|
21242
22349
|
useInput16((input, key) => {
|
|
@@ -21245,17 +22352,17 @@ var SubmitButton = (props) => {
|
|
|
21245
22352
|
}
|
|
21246
22353
|
});
|
|
21247
22354
|
return React23.createElement(
|
|
21248
|
-
|
|
22355
|
+
Box23,
|
|
21249
22356
|
{ marginRight: 2 },
|
|
21250
22357
|
React23.createElement(
|
|
21251
|
-
|
|
22358
|
+
Box23,
|
|
21252
22359
|
{ marginRight: 2, paddingY: 1 },
|
|
21253
|
-
React23.createElement(
|
|
22360
|
+
React23.createElement(Text21, null, !props.canSubmit ? "There are still required inputs you have not completed yet." : isFocused ? "Press Enter to submit form" : "Use the arrow keys to navigate to the submit button.")
|
|
21254
22361
|
),
|
|
21255
22362
|
React23.createElement(
|
|
21256
|
-
|
|
22363
|
+
Box23,
|
|
21257
22364
|
{ borderStyle: "round", borderColor: !props.canSubmit ? "gray" : isFocused ? "blue" : "white", paddingX: 2 },
|
|
21258
|
-
React23.createElement(
|
|
22365
|
+
React23.createElement(Text21, { color: !props.canSubmit ? "gray" : isFocused ? "blue" : "white", bold: true, underline: isFocused }, props.canSubmit ? "Submit form" : "Cannot submit form yet")
|
|
21259
22366
|
)
|
|
21260
22367
|
);
|
|
21261
22368
|
};
|
|
@@ -21296,17 +22403,17 @@ var Form = (props) => {
|
|
|
21296
22403
|
}
|
|
21297
22404
|
}, { isActive: !editingField });
|
|
21298
22405
|
return React24.createElement(
|
|
21299
|
-
|
|
22406
|
+
Box24,
|
|
21300
22407
|
{ width: "100%", height: "100%", flexDirection: "column" },
|
|
21301
22408
|
React24.createElement(FormHeader, { ...props, currentTab, onChangeTab: setCurrentTab, editingField }),
|
|
21302
22409
|
!editingField && props.form.sections[currentTab].description && React24.createElement(
|
|
21303
|
-
|
|
22410
|
+
Box24,
|
|
21304
22411
|
{ marginX: 4 },
|
|
21305
22412
|
React24.createElement(DescriptionRenderer, { description: props.form.sections[currentTab].description })
|
|
21306
22413
|
),
|
|
21307
|
-
React24.createElement(
|
|
22414
|
+
React24.createElement(Box24, { flexDirection: "column" }, currentTab > props.form.sections.length - 1 ? null : props.form.sections[currentTab].fields.map((field) => React24.createElement(FormFieldRenderer, { field, key: field.name, form: props.form, value: value[field.name], onChange: (v) => setValueAndPropagate({ ...value, [field.name]: v }), onSetEditingField: setEditingField, editingField, customManagers: props.customManagers }))),
|
|
21308
22415
|
!editingField && React24.createElement(
|
|
21309
|
-
|
|
22416
|
+
Box24,
|
|
21310
22417
|
{ flexDirection: "row-reverse" },
|
|
21311
22418
|
React24.createElement(SubmitButton, { canSubmit: canSubmitForm, onSubmit: () => props.onSubmit?.(value) })
|
|
21312
22419
|
)
|
|
@@ -21578,7 +22685,7 @@ function missingRequiredFields(schema, decoded, rawValues = {}) {
|
|
|
21578
22685
|
}
|
|
21579
22686
|
|
|
21580
22687
|
// src/components/ToolTestModal.tsx
|
|
21581
|
-
import { Fragment as
|
|
22688
|
+
import { Fragment as Fragment10, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
21582
22689
|
function ToolTestModal({
|
|
21583
22690
|
tool,
|
|
21584
22691
|
inspectorClient,
|
|
@@ -21704,8 +22811,8 @@ function ToolTestModal({
|
|
|
21704
22811
|
};
|
|
21705
22812
|
const modalWidth = terminalDimensions.width - 2;
|
|
21706
22813
|
const modalHeight = terminalDimensions.height - 2;
|
|
21707
|
-
return /* @__PURE__ */
|
|
21708
|
-
|
|
22814
|
+
return /* @__PURE__ */ jsx14(
|
|
22815
|
+
Box25,
|
|
21709
22816
|
{
|
|
21710
22817
|
position: "absolute",
|
|
21711
22818
|
width: terminalDimensions.width,
|
|
@@ -21713,8 +22820,8 @@ function ToolTestModal({
|
|
|
21713
22820
|
flexDirection: "column",
|
|
21714
22821
|
justifyContent: "center",
|
|
21715
22822
|
alignItems: "center",
|
|
21716
|
-
children: /* @__PURE__ */
|
|
21717
|
-
|
|
22823
|
+
children: /* @__PURE__ */ jsxs13(
|
|
22824
|
+
Box25,
|
|
21718
22825
|
{
|
|
21719
22826
|
width: modalWidth,
|
|
21720
22827
|
height: modalHeight,
|
|
@@ -21725,40 +22832,40 @@ function ToolTestModal({
|
|
|
21725
22832
|
paddingY: 1,
|
|
21726
22833
|
backgroundColor: "black",
|
|
21727
22834
|
children: [
|
|
21728
|
-
/* @__PURE__ */
|
|
21729
|
-
/* @__PURE__ */
|
|
21730
|
-
/* @__PURE__ */
|
|
21731
|
-
/* @__PURE__ */
|
|
22835
|
+
/* @__PURE__ */ jsxs13(Box25, { flexShrink: 0, marginBottom: 1, children: [
|
|
22836
|
+
/* @__PURE__ */ jsx14(Text22, { bold: true, color: "cyan", children: formStructure.title }),
|
|
22837
|
+
/* @__PURE__ */ jsx14(Text22, { children: " " }),
|
|
22838
|
+
/* @__PURE__ */ jsx14(Text22, { dimColor: true, children: "(Press ESC to close)" })
|
|
21732
22839
|
] }),
|
|
21733
|
-
/* @__PURE__ */
|
|
21734
|
-
state === "form" && /* @__PURE__ */
|
|
22840
|
+
/* @__PURE__ */ jsxs13(Box25, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
|
|
22841
|
+
state === "form" && /* @__PURE__ */ jsx14(Box25, { flexGrow: 1, width: "100%", children: /* @__PURE__ */ jsx14(
|
|
21735
22842
|
Form,
|
|
21736
22843
|
{
|
|
21737
22844
|
form: formStructure,
|
|
21738
22845
|
onSubmit: (value) => void handleFormSubmit(value)
|
|
21739
22846
|
}
|
|
21740
22847
|
) }),
|
|
21741
|
-
state === "loading" && /* @__PURE__ */
|
|
21742
|
-
state === "results" && result && /* @__PURE__ */
|
|
21743
|
-
/* @__PURE__ */
|
|
22848
|
+
state === "loading" && /* @__PURE__ */ jsx14(Box25, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx14(Text22, { color: "yellow", children: "Calling tool..." }) }),
|
|
22849
|
+
state === "results" && result && /* @__PURE__ */ jsx14(Box25, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ jsxs13(ScrollView, { ref: scrollViewRef, children: [
|
|
22850
|
+
/* @__PURE__ */ jsx14(Box25, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs13(Text22, { bold: true, color: "green", children: [
|
|
21744
22851
|
"Duration: ",
|
|
21745
22852
|
result.duration,
|
|
21746
22853
|
"ms"
|
|
21747
22854
|
] }) }),
|
|
21748
|
-
/* @__PURE__ */
|
|
21749
|
-
/* @__PURE__ */
|
|
21750
|
-
/* @__PURE__ */
|
|
22855
|
+
/* @__PURE__ */ jsxs13(Box25, { marginBottom: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
22856
|
+
/* @__PURE__ */ jsx14(Text22, { bold: true, color: "cyan", children: "Input:" }),
|
|
22857
|
+
/* @__PURE__ */ jsx14(Box25, { paddingLeft: 2, children: /* @__PURE__ */ jsx14(Text22, { dimColor: true, children: JSON.stringify(result.input, null, 2) }) })
|
|
21751
22858
|
] }),
|
|
21752
|
-
result.error ? /* @__PURE__ */
|
|
21753
|
-
/* @__PURE__ */
|
|
21754
|
-
/* @__PURE__ */
|
|
21755
|
-
result.errorDetails != null ? /* @__PURE__ */
|
|
21756
|
-
/* @__PURE__ */
|
|
21757
|
-
/* @__PURE__ */
|
|
22859
|
+
result.error ? /* @__PURE__ */ jsxs13(Box25, { flexShrink: 0, flexDirection: "column", children: [
|
|
22860
|
+
/* @__PURE__ */ jsx14(Text22, { bold: true, color: "red", children: "Error:" }),
|
|
22861
|
+
/* @__PURE__ */ jsx14(Box25, { paddingLeft: 2, children: /* @__PURE__ */ jsx14(Text22, { color: "red", children: String(result.error) }) }),
|
|
22862
|
+
result.errorDetails != null ? /* @__PURE__ */ jsxs13(Fragment10, { children: [
|
|
22863
|
+
/* @__PURE__ */ jsx14(Box25, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text22, { bold: true, color: "red", dimColor: true, children: "Error Details:" }) }),
|
|
22864
|
+
/* @__PURE__ */ jsx14(Box25, { paddingLeft: 2, children: /* @__PURE__ */ jsx14(Text22, { dimColor: true, children: JSON.stringify(result.errorDetails, null, 2) }) })
|
|
21758
22865
|
] }) : null
|
|
21759
|
-
] }) : /* @__PURE__ */
|
|
21760
|
-
/* @__PURE__ */
|
|
21761
|
-
/* @__PURE__ */
|
|
22866
|
+
] }) : /* @__PURE__ */ jsxs13(Box25, { flexShrink: 0, flexDirection: "column", children: [
|
|
22867
|
+
/* @__PURE__ */ jsx14(Text22, { bold: true, color: "green", children: "Output:" }),
|
|
22868
|
+
/* @__PURE__ */ jsx14(Box25, { paddingLeft: 2, children: /* @__PURE__ */ jsx14(Text22, { dimColor: true, children: JSON.stringify(result.output, null, 2) }) })
|
|
21762
22869
|
] })
|
|
21763
22870
|
] }) })
|
|
21764
22871
|
] })
|
|
@@ -21771,7 +22878,7 @@ function ToolTestModal({
|
|
|
21771
22878
|
|
|
21772
22879
|
// src/components/ResourceTestModal.tsx
|
|
21773
22880
|
import React27, { useState as useState15 } from "react";
|
|
21774
|
-
import { Box as
|
|
22881
|
+
import { Box as Box26, Text as Text23, useInput as useInput19 } from "ink";
|
|
21775
22882
|
|
|
21776
22883
|
// src/utils/uriTemplateToForm.ts
|
|
21777
22884
|
import { UriTemplate as UriTemplate2 } from "@modelcontextprotocol/client";
|
|
@@ -21804,7 +22911,7 @@ function uriTemplateToForm(uriTemplate, templateName) {
|
|
|
21804
22911
|
}
|
|
21805
22912
|
|
|
21806
22913
|
// src/components/ResourceTestModal.tsx
|
|
21807
|
-
import { Fragment as
|
|
22914
|
+
import { Fragment as Fragment11, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
21808
22915
|
function getErrorMessage(error) {
|
|
21809
22916
|
if (error instanceof Error) {
|
|
21810
22917
|
return error.message;
|
|
@@ -21953,8 +23060,8 @@ function ResourceTestModal({
|
|
|
21953
23060
|
};
|
|
21954
23061
|
const modalWidth = terminalDimensions.width - 2;
|
|
21955
23062
|
const modalHeight = terminalDimensions.height - 2;
|
|
21956
|
-
return /* @__PURE__ */
|
|
21957
|
-
|
|
23063
|
+
return /* @__PURE__ */ jsx15(
|
|
23064
|
+
Box26,
|
|
21958
23065
|
{
|
|
21959
23066
|
position: "absolute",
|
|
21960
23067
|
width: terminalDimensions.width,
|
|
@@ -21962,8 +23069,8 @@ function ResourceTestModal({
|
|
|
21962
23069
|
flexDirection: "column",
|
|
21963
23070
|
justifyContent: "center",
|
|
21964
23071
|
alignItems: "center",
|
|
21965
|
-
children: /* @__PURE__ */
|
|
21966
|
-
|
|
23072
|
+
children: /* @__PURE__ */ jsxs14(
|
|
23073
|
+
Box26,
|
|
21967
23074
|
{
|
|
21968
23075
|
width: modalWidth,
|
|
21969
23076
|
height: modalHeight,
|
|
@@ -21974,15 +23081,15 @@ function ResourceTestModal({
|
|
|
21974
23081
|
paddingY: 1,
|
|
21975
23082
|
backgroundColor: "black",
|
|
21976
23083
|
children: [
|
|
21977
|
-
/* @__PURE__ */
|
|
21978
|
-
/* @__PURE__ */
|
|
21979
|
-
/* @__PURE__ */
|
|
21980
|
-
/* @__PURE__ */
|
|
23084
|
+
/* @__PURE__ */ jsxs14(Box26, { flexShrink: 0, marginBottom: 1, children: [
|
|
23085
|
+
/* @__PURE__ */ jsx15(Text23, { bold: true, color: "cyan", children: formStructure.title }),
|
|
23086
|
+
/* @__PURE__ */ jsx15(Text23, { children: " " }),
|
|
23087
|
+
/* @__PURE__ */ jsx15(Text23, { dimColor: true, children: "(Press ESC to close)" })
|
|
21981
23088
|
] }),
|
|
21982
|
-
/* @__PURE__ */
|
|
21983
|
-
state === "form" && /* @__PURE__ */
|
|
21984
|
-
template.description && /* @__PURE__ */
|
|
21985
|
-
/* @__PURE__ */
|
|
23089
|
+
/* @__PURE__ */ jsxs14(Box26, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
|
|
23090
|
+
state === "form" && /* @__PURE__ */ jsxs14(Box26, { flexGrow: 1, flexDirection: "column", children: [
|
|
23091
|
+
template.description && /* @__PURE__ */ jsx15(Box26, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ jsx15(Text23, { dimColor: true, children: template.description }) }),
|
|
23092
|
+
/* @__PURE__ */ jsx15(
|
|
21986
23093
|
Form,
|
|
21987
23094
|
{
|
|
21988
23095
|
form: formStructure,
|
|
@@ -21990,34 +23097,34 @@ function ResourceTestModal({
|
|
|
21990
23097
|
}
|
|
21991
23098
|
)
|
|
21992
23099
|
] }),
|
|
21993
|
-
state === "loading" && /* @__PURE__ */
|
|
21994
|
-
state === "results" && result && /* @__PURE__ */
|
|
21995
|
-
/* @__PURE__ */
|
|
23100
|
+
state === "loading" && /* @__PURE__ */ jsx15(Box26, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx15(Text23, { color: "yellow", children: "Reading resource..." }) }),
|
|
23101
|
+
state === "results" && result && /* @__PURE__ */ jsx15(Box26, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ jsxs14(ScrollView, { ref: scrollViewRef, children: [
|
|
23102
|
+
/* @__PURE__ */ jsx15(Box26, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs14(Text23, { bold: true, color: "green", children: [
|
|
21996
23103
|
"Duration: ",
|
|
21997
23104
|
result.duration,
|
|
21998
23105
|
"ms"
|
|
21999
23106
|
] }) }),
|
|
22000
|
-
/* @__PURE__ */
|
|
22001
|
-
/* @__PURE__ */
|
|
23107
|
+
/* @__PURE__ */ jsxs14(Box26, { marginBottom: 1, flexShrink: 0, children: [
|
|
23108
|
+
/* @__PURE__ */ jsxs14(Text23, { bold: true, color: "cyan", children: [
|
|
22002
23109
|
"URI:",
|
|
22003
23110
|
" "
|
|
22004
23111
|
] }),
|
|
22005
|
-
/* @__PURE__ */
|
|
23112
|
+
/* @__PURE__ */ jsx15(Text23, { dimColor: true, children: result.uri })
|
|
22006
23113
|
] }),
|
|
22007
|
-
/* @__PURE__ */
|
|
22008
|
-
/* @__PURE__ */
|
|
22009
|
-
/* @__PURE__ */
|
|
23114
|
+
/* @__PURE__ */ jsxs14(Box26, { marginBottom: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
23115
|
+
/* @__PURE__ */ jsx15(Text23, { bold: true, color: "cyan", children: "Template Values:" }),
|
|
23116
|
+
/* @__PURE__ */ jsx15(Box26, { paddingLeft: 2, children: /* @__PURE__ */ jsx15(Text23, { dimColor: true, children: JSON.stringify(result.input, null, 2) }) })
|
|
22010
23117
|
] }),
|
|
22011
|
-
result.error ? /* @__PURE__ */
|
|
22012
|
-
/* @__PURE__ */
|
|
22013
|
-
/* @__PURE__ */
|
|
22014
|
-
result.errorDetails != null ? /* @__PURE__ */
|
|
22015
|
-
/* @__PURE__ */
|
|
22016
|
-
/* @__PURE__ */
|
|
23118
|
+
result.error ? /* @__PURE__ */ jsxs14(Box26, { flexShrink: 0, flexDirection: "column", children: [
|
|
23119
|
+
/* @__PURE__ */ jsx15(Box26, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx15(Text23, { bold: true, color: "red", children: "Error:" }) }),
|
|
23120
|
+
/* @__PURE__ */ jsx15(Box26, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx15(Text23, { color: "red", children: String(result.error) }) }),
|
|
23121
|
+
result.errorDetails != null ? /* @__PURE__ */ jsxs14(Fragment11, { children: [
|
|
23122
|
+
/* @__PURE__ */ jsx15(Box26, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx15(Text23, { bold: true, color: "red", dimColor: true, children: "Error Details:" }) }),
|
|
23123
|
+
/* @__PURE__ */ jsx15(Box26, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx15(Text23, { dimColor: true, children: JSON.stringify(result.errorDetails, null, 2) }) })
|
|
22017
23124
|
] }) : null
|
|
22018
|
-
] }) : /* @__PURE__ */
|
|
22019
|
-
/* @__PURE__ */
|
|
22020
|
-
/* @__PURE__ */
|
|
23125
|
+
] }) : /* @__PURE__ */ jsxs14(Box26, { flexShrink: 0, flexDirection: "column", children: [
|
|
23126
|
+
/* @__PURE__ */ jsx15(Text23, { bold: true, color: "green", children: "Resource Content:" }),
|
|
23127
|
+
/* @__PURE__ */ jsx15(Box26, { paddingLeft: 2, children: /* @__PURE__ */ jsx15(Text23, { dimColor: true, children: JSON.stringify(result.output, null, 2) }) })
|
|
22021
23128
|
] })
|
|
22022
23129
|
] }) })
|
|
22023
23130
|
] })
|
|
@@ -22030,7 +23137,7 @@ function ResourceTestModal({
|
|
|
22030
23137
|
|
|
22031
23138
|
// src/components/PromptTestModal.tsx
|
|
22032
23139
|
import React28, { useState as useState16 } from "react";
|
|
22033
|
-
import { Box as
|
|
23140
|
+
import { Box as Box27, Text as Text24, useInput as useInput20 } from "ink";
|
|
22034
23141
|
|
|
22035
23142
|
// src/utils/promptArgsToForm.ts
|
|
22036
23143
|
function promptArgsToForm(promptArguments, promptName) {
|
|
@@ -22066,7 +23173,7 @@ function promptArgsToForm(promptArguments, promptName) {
|
|
|
22066
23173
|
}
|
|
22067
23174
|
|
|
22068
23175
|
// src/components/PromptTestModal.tsx
|
|
22069
|
-
import { Fragment as
|
|
23176
|
+
import { Fragment as Fragment12, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
22070
23177
|
function getErrorMessage2(error) {
|
|
22071
23178
|
if (error instanceof Error) {
|
|
22072
23179
|
return error.message;
|
|
@@ -22188,8 +23295,8 @@ function PromptTestModal({
|
|
|
22188
23295
|
};
|
|
22189
23296
|
const modalWidth = terminalDimensions.width - 2;
|
|
22190
23297
|
const modalHeight = terminalDimensions.height - 2;
|
|
22191
|
-
return /* @__PURE__ */
|
|
22192
|
-
|
|
23298
|
+
return /* @__PURE__ */ jsx16(
|
|
23299
|
+
Box27,
|
|
22193
23300
|
{
|
|
22194
23301
|
position: "absolute",
|
|
22195
23302
|
width: terminalDimensions.width,
|
|
@@ -22197,8 +23304,8 @@ function PromptTestModal({
|
|
|
22197
23304
|
flexDirection: "column",
|
|
22198
23305
|
justifyContent: "center",
|
|
22199
23306
|
alignItems: "center",
|
|
22200
|
-
children: /* @__PURE__ */
|
|
22201
|
-
|
|
23307
|
+
children: /* @__PURE__ */ jsxs15(
|
|
23308
|
+
Box27,
|
|
22202
23309
|
{
|
|
22203
23310
|
width: modalWidth,
|
|
22204
23311
|
height: modalHeight,
|
|
@@ -22209,15 +23316,15 @@ function PromptTestModal({
|
|
|
22209
23316
|
paddingY: 1,
|
|
22210
23317
|
backgroundColor: "black",
|
|
22211
23318
|
children: [
|
|
22212
|
-
/* @__PURE__ */
|
|
22213
|
-
/* @__PURE__ */
|
|
22214
|
-
/* @__PURE__ */
|
|
22215
|
-
/* @__PURE__ */
|
|
23319
|
+
/* @__PURE__ */ jsxs15(Box27, { flexShrink: 0, marginBottom: 1, children: [
|
|
23320
|
+
/* @__PURE__ */ jsx16(Text24, { bold: true, color: "cyan", children: formStructure.title }),
|
|
23321
|
+
/* @__PURE__ */ jsx16(Text24, { children: " " }),
|
|
23322
|
+
/* @__PURE__ */ jsx16(Text24, { dimColor: true, children: "(Press ESC to close)" })
|
|
22216
23323
|
] }),
|
|
22217
|
-
/* @__PURE__ */
|
|
22218
|
-
state === "form" && /* @__PURE__ */
|
|
22219
|
-
prompt.description && /* @__PURE__ */
|
|
22220
|
-
/* @__PURE__ */
|
|
23324
|
+
/* @__PURE__ */ jsxs15(Box27, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
|
|
23325
|
+
state === "form" && /* @__PURE__ */ jsxs15(Box27, { flexGrow: 1, flexDirection: "column", children: [
|
|
23326
|
+
prompt.description && /* @__PURE__ */ jsx16(Box27, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text24, { dimColor: true, children: prompt.description }) }),
|
|
23327
|
+
/* @__PURE__ */ jsx16(
|
|
22221
23328
|
Form,
|
|
22222
23329
|
{
|
|
22223
23330
|
form: formStructure,
|
|
@@ -22225,27 +23332,27 @@ function PromptTestModal({
|
|
|
22225
23332
|
}
|
|
22226
23333
|
)
|
|
22227
23334
|
] }),
|
|
22228
|
-
state === "loading" && /* @__PURE__ */
|
|
22229
|
-
state === "results" && result && /* @__PURE__ */
|
|
22230
|
-
/* @__PURE__ */
|
|
23335
|
+
state === "loading" && /* @__PURE__ */ jsx16(Box27, { flexGrow: 1, justifyContent: "center", alignItems: "center", children: /* @__PURE__ */ jsx16(Text24, { color: "yellow", children: "Getting prompt..." }) }),
|
|
23336
|
+
state === "results" && result && /* @__PURE__ */ jsx16(Box27, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ jsxs15(ScrollView, { ref: scrollViewRef, children: [
|
|
23337
|
+
/* @__PURE__ */ jsx16(Box27, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs15(Text24, { bold: true, color: "green", children: [
|
|
22231
23338
|
"Duration: ",
|
|
22232
23339
|
result.duration,
|
|
22233
23340
|
"ms"
|
|
22234
23341
|
] }) }),
|
|
22235
|
-
Object.keys(result.input).length > 0 && /* @__PURE__ */
|
|
22236
|
-
/* @__PURE__ */
|
|
22237
|
-
/* @__PURE__ */
|
|
23342
|
+
Object.keys(result.input).length > 0 && /* @__PURE__ */ jsxs15(Box27, { marginBottom: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
23343
|
+
/* @__PURE__ */ jsx16(Text24, { bold: true, color: "cyan", children: "Arguments:" }),
|
|
23344
|
+
/* @__PURE__ */ jsx16(Box27, { paddingLeft: 2, children: /* @__PURE__ */ jsx16(Text24, { dimColor: true, children: JSON.stringify(result.input, null, 2) }) })
|
|
22238
23345
|
] }),
|
|
22239
|
-
result.error ? /* @__PURE__ */
|
|
22240
|
-
/* @__PURE__ */
|
|
22241
|
-
/* @__PURE__ */
|
|
22242
|
-
result.errorDetails != null ? /* @__PURE__ */
|
|
22243
|
-
/* @__PURE__ */
|
|
22244
|
-
/* @__PURE__ */
|
|
23346
|
+
result.error ? /* @__PURE__ */ jsxs15(Box27, { flexShrink: 0, flexDirection: "column", children: [
|
|
23347
|
+
/* @__PURE__ */ jsx16(Box27, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text24, { bold: true, color: "red", children: "Error:" }) }),
|
|
23348
|
+
/* @__PURE__ */ jsx16(Box27, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text24, { color: "red", children: String(result.error) }) }),
|
|
23349
|
+
result.errorDetails != null ? /* @__PURE__ */ jsxs15(Fragment12, { children: [
|
|
23350
|
+
/* @__PURE__ */ jsx16(Box27, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text24, { bold: true, color: "red", dimColor: true, children: "Error Details:" }) }),
|
|
23351
|
+
/* @__PURE__ */ jsx16(Box27, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text24, { dimColor: true, children: JSON.stringify(result.errorDetails, null, 2) }) })
|
|
22245
23352
|
] }) : null
|
|
22246
|
-
] }) : /* @__PURE__ */
|
|
22247
|
-
/* @__PURE__ */
|
|
22248
|
-
/* @__PURE__ */
|
|
23353
|
+
] }) : /* @__PURE__ */ jsxs15(Box27, { flexShrink: 0, flexDirection: "column", children: [
|
|
23354
|
+
/* @__PURE__ */ jsx16(Text24, { bold: true, color: "green", children: "Prompt Messages:" }),
|
|
23355
|
+
/* @__PURE__ */ jsx16(Box27, { paddingLeft: 2, children: /* @__PURE__ */ jsx16(Text24, { dimColor: true, children: JSON.stringify(result.output, null, 2) }) })
|
|
22249
23356
|
] })
|
|
22250
23357
|
] }) })
|
|
22251
23358
|
] })
|
|
@@ -22258,8 +23365,8 @@ function PromptTestModal({
|
|
|
22258
23365
|
|
|
22259
23366
|
// src/components/DetailsModal.tsx
|
|
22260
23367
|
import React29, { useRef as useRef14 } from "react";
|
|
22261
|
-
import { Box as
|
|
22262
|
-
import { jsx as
|
|
23368
|
+
import { Box as Box28, Text as Text25, useInput as useInput21 } from "ink";
|
|
23369
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
22263
23370
|
function DetailsModal({
|
|
22264
23371
|
title,
|
|
22265
23372
|
content,
|
|
@@ -22305,8 +23412,8 @@ function DetailsModal({
|
|
|
22305
23412
|
);
|
|
22306
23413
|
const modalWidth = terminalDimensions.width - 2;
|
|
22307
23414
|
const modalHeight = terminalDimensions.height - 2;
|
|
22308
|
-
return /* @__PURE__ */
|
|
22309
|
-
|
|
23415
|
+
return /* @__PURE__ */ jsx17(
|
|
23416
|
+
Box28,
|
|
22310
23417
|
{
|
|
22311
23418
|
position: "absolute",
|
|
22312
23419
|
width: terminalDimensions.width,
|
|
@@ -22314,8 +23421,8 @@ function DetailsModal({
|
|
|
22314
23421
|
flexDirection: "column",
|
|
22315
23422
|
justifyContent: "center",
|
|
22316
23423
|
alignItems: "center",
|
|
22317
|
-
children: /* @__PURE__ */
|
|
22318
|
-
|
|
23424
|
+
children: /* @__PURE__ */ jsxs16(
|
|
23425
|
+
Box28,
|
|
22319
23426
|
{
|
|
22320
23427
|
width: modalWidth,
|
|
22321
23428
|
height: modalHeight,
|
|
@@ -22326,12 +23433,12 @@ function DetailsModal({
|
|
|
22326
23433
|
paddingY: 1,
|
|
22327
23434
|
backgroundColor: "black",
|
|
22328
23435
|
children: [
|
|
22329
|
-
/* @__PURE__ */
|
|
22330
|
-
/* @__PURE__ */
|
|
22331
|
-
/* @__PURE__ */
|
|
22332
|
-
/* @__PURE__ */
|
|
23436
|
+
/* @__PURE__ */ jsxs16(Box28, { flexShrink: 0, marginBottom: 1, children: [
|
|
23437
|
+
/* @__PURE__ */ jsx17(Text25, { bold: true, color: "cyan", children: title }),
|
|
23438
|
+
/* @__PURE__ */ jsx17(Text25, { children: " " }),
|
|
23439
|
+
/* @__PURE__ */ jsx17(Text25, { dimColor: true, children: "(Press ESC to close)" })
|
|
22333
23440
|
] }),
|
|
22334
|
-
/* @__PURE__ */
|
|
23441
|
+
/* @__PURE__ */ jsx17(Box28, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ jsx17(ScrollView, { ref: scrollViewRef, children: content }) })
|
|
22335
23442
|
]
|
|
22336
23443
|
}
|
|
22337
23444
|
)
|
|
@@ -22340,7 +23447,7 @@ function DetailsModal({
|
|
|
22340
23447
|
}
|
|
22341
23448
|
|
|
22342
23449
|
// src/App.tsx
|
|
22343
|
-
import { Fragment as
|
|
23450
|
+
import { Fragment as Fragment13, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
22344
23451
|
var APP_NAME = "MCP Inspector TUI";
|
|
22345
23452
|
var APP_DESCRIPTION = "Terminal User Interface for the Model Context Protocol Inspector";
|
|
22346
23453
|
var APP_VERSION = readInspectorVersion(import.meta.url);
|
|
@@ -23028,48 +24135,48 @@ function App({
|
|
|
23028
24135
|
managedTools,
|
|
23029
24136
|
inspectorStderrLogs
|
|
23030
24137
|
]);
|
|
23031
|
-
const renderResourceDetails = (resource) => /* @__PURE__ */
|
|
23032
|
-
"uri" in resource && resource.description && /* @__PURE__ */
|
|
23033
|
-
|
|
24138
|
+
const renderResourceDetails = (resource) => /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24139
|
+
"uri" in resource && resource.description && /* @__PURE__ */ jsx18(Fragment13, { children: resource.description.split("\n").map((line, idx) => /* @__PURE__ */ jsx18(
|
|
24140
|
+
Box29,
|
|
23034
24141
|
{
|
|
23035
24142
|
marginTop: idx === 0 ? 0 : 0,
|
|
23036
24143
|
flexShrink: 0,
|
|
23037
|
-
children: /* @__PURE__ */
|
|
24144
|
+
children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: line })
|
|
23038
24145
|
},
|
|
23039
24146
|
`desc-${idx}`
|
|
23040
24147
|
)) }),
|
|
23041
|
-
"uri" in resource && resource.uri && /* @__PURE__ */
|
|
23042
|
-
/* @__PURE__ */
|
|
23043
|
-
/* @__PURE__ */
|
|
24148
|
+
"uri" in resource && resource.uri && /* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, children: [
|
|
24149
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "URI:" }),
|
|
24150
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: resource.uri }) })
|
|
23044
24151
|
] }),
|
|
23045
|
-
"mimeType" in resource && resource.mimeType && /* @__PURE__ */
|
|
23046
|
-
/* @__PURE__ */
|
|
23047
|
-
/* @__PURE__ */
|
|
24152
|
+
"mimeType" in resource && resource.mimeType && /* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, children: [
|
|
24153
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "MIME Type:" }),
|
|
24154
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: resource.mimeType }) })
|
|
23048
24155
|
] }),
|
|
23049
|
-
/* @__PURE__ */
|
|
23050
|
-
/* @__PURE__ */
|
|
23051
|
-
/* @__PURE__ */
|
|
24156
|
+
/* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24157
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Full JSON:" }),
|
|
24158
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(resource, null, 2) }) })
|
|
23052
24159
|
] })
|
|
23053
24160
|
] });
|
|
23054
|
-
const renderPromptDetails = (prompt) => /* @__PURE__ */
|
|
23055
|
-
prompt.description && /* @__PURE__ */
|
|
23056
|
-
|
|
24161
|
+
const renderPromptDetails = (prompt) => /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24162
|
+
prompt.description && /* @__PURE__ */ jsx18(Fragment13, { children: prompt.description.split("\n").map((line, idx) => /* @__PURE__ */ jsx18(
|
|
24163
|
+
Box29,
|
|
23057
24164
|
{
|
|
23058
24165
|
marginTop: idx === 0 ? 0 : 0,
|
|
23059
24166
|
flexShrink: 0,
|
|
23060
|
-
children: /* @__PURE__ */
|
|
24167
|
+
children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: line })
|
|
23061
24168
|
},
|
|
23062
24169
|
`desc-${idx}`
|
|
23063
24170
|
)) }),
|
|
23064
|
-
prompt.arguments && prompt.arguments.length > 0 && /* @__PURE__ */
|
|
23065
|
-
/* @__PURE__ */
|
|
23066
|
-
prompt.arguments.map((arg, idx) => /* @__PURE__ */
|
|
23067
|
-
|
|
24171
|
+
prompt.arguments && prompt.arguments.length > 0 && /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24172
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx18(Text26, { bold: true, children: "Arguments:" }) }),
|
|
24173
|
+
prompt.arguments.map((arg, idx) => /* @__PURE__ */ jsx18(
|
|
24174
|
+
Box29,
|
|
23068
24175
|
{
|
|
23069
24176
|
marginTop: 1,
|
|
23070
24177
|
paddingLeft: 2,
|
|
23071
24178
|
flexShrink: 0,
|
|
23072
|
-
children: /* @__PURE__ */
|
|
24179
|
+
children: /* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23073
24180
|
"- ",
|
|
23074
24181
|
arg.name,
|
|
23075
24182
|
":",
|
|
@@ -23080,134 +24187,102 @@ function App({
|
|
|
23080
24187
|
`arg-${idx}`
|
|
23081
24188
|
))
|
|
23082
24189
|
] }),
|
|
23083
|
-
/* @__PURE__ */
|
|
23084
|
-
/* @__PURE__ */
|
|
23085
|
-
/* @__PURE__ */
|
|
24190
|
+
/* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24191
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Full JSON:" }),
|
|
24192
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(prompt, null, 2) }) })
|
|
23086
24193
|
] })
|
|
23087
24194
|
] });
|
|
23088
|
-
const renderToolDetails = (tool) => /* @__PURE__ */
|
|
23089
|
-
tool.description && /* @__PURE__ */
|
|
23090
|
-
|
|
24195
|
+
const renderToolDetails = (tool) => /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24196
|
+
tool.description && /* @__PURE__ */ jsx18(Fragment13, { children: tool.description.split("\n").map((line, idx) => /* @__PURE__ */ jsx18(
|
|
24197
|
+
Box29,
|
|
23091
24198
|
{
|
|
23092
24199
|
marginTop: idx === 0 ? 0 : 0,
|
|
23093
24200
|
flexShrink: 0,
|
|
23094
|
-
children: /* @__PURE__ */
|
|
24201
|
+
children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: line })
|
|
23095
24202
|
},
|
|
23096
24203
|
`desc-${idx}`
|
|
23097
24204
|
)) }),
|
|
23098
|
-
tool.inputSchema && /* @__PURE__ */
|
|
23099
|
-
/* @__PURE__ */
|
|
23100
|
-
/* @__PURE__ */
|
|
24205
|
+
tool.inputSchema && /* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24206
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Input Schema:" }),
|
|
24207
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(tool.inputSchema, null, 2) }) })
|
|
23101
24208
|
] }),
|
|
23102
|
-
/* @__PURE__ */
|
|
23103
|
-
/* @__PURE__ */
|
|
23104
|
-
/* @__PURE__ */
|
|
24209
|
+
/* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24210
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Full JSON:" }),
|
|
24211
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(tool, null, 2) }) })
|
|
23105
24212
|
] })
|
|
23106
24213
|
] });
|
|
23107
|
-
const renderRequestDetails = (request) => /* @__PURE__ */
|
|
23108
|
-
/* @__PURE__ */
|
|
24214
|
+
const renderRequestDetails = (request) => /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24215
|
+
/* @__PURE__ */ jsx18(Box29, { flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { bold: true, children: [
|
|
23109
24216
|
request.method,
|
|
23110
24217
|
" ",
|
|
23111
24218
|
request.url
|
|
23112
24219
|
] }) }),
|
|
23113
|
-
/* @__PURE__ */
|
|
24220
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { bold: true, children: [
|
|
23114
24221
|
"Category:",
|
|
23115
24222
|
" ",
|
|
23116
|
-
/* @__PURE__ */
|
|
24223
|
+
/* @__PURE__ */ jsx18(Text26, { children: request.category === "auth" ? "auth" : "transport" })
|
|
23117
24224
|
] }) }),
|
|
23118
|
-
request.responseStatus !== void 0 ? /* @__PURE__ */
|
|
24225
|
+
request.responseStatus !== void 0 ? /* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { bold: true, children: [
|
|
23119
24226
|
"Status: ",
|
|
23120
24227
|
request.responseStatus,
|
|
23121
24228
|
" ",
|
|
23122
24229
|
request.responseStatusText || ""
|
|
23123
|
-
] }) }) : request.error ? /* @__PURE__ */
|
|
24230
|
+
] }) }) : request.error ? /* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { bold: true, color: "red", children: [
|
|
23124
24231
|
"Error: ",
|
|
23125
24232
|
request.error
|
|
23126
24233
|
] }) }) : null,
|
|
23127
|
-
request.duration !== void 0 && /* @__PURE__ */
|
|
24234
|
+
request.duration !== void 0 && /* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23128
24235
|
request.timestamp.toLocaleTimeString(),
|
|
23129
24236
|
" (",
|
|
23130
24237
|
request.duration,
|
|
23131
24238
|
"ms)"
|
|
23132
24239
|
] }) }),
|
|
23133
|
-
/* @__PURE__ */
|
|
23134
|
-
/* @__PURE__ */
|
|
23135
|
-
Object.entries(request.requestHeaders).map(([key, value]) => /* @__PURE__ */
|
|
24240
|
+
/* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, children: [
|
|
24241
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Request Headers:" }),
|
|
24242
|
+
Object.entries(request.requestHeaders).map(([key, value]) => /* @__PURE__ */ jsx18(Box29, { marginTop: 0, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23136
24243
|
key,
|
|
23137
24244
|
": ",
|
|
23138
24245
|
value
|
|
23139
24246
|
] }) }, key))
|
|
23140
24247
|
] }),
|
|
23141
|
-
request.requestBody && /* @__PURE__ */
|
|
23142
|
-
/* @__PURE__ */
|
|
23143
|
-
(
|
|
23144
|
-
try {
|
|
23145
|
-
const parsed = JSON.parse(request.requestBody);
|
|
23146
|
-
return JSON.stringify(parsed, null, 2).split("\n").map((line, idx) => /* @__PURE__ */ jsx17(
|
|
23147
|
-
Box28,
|
|
23148
|
-
{
|
|
23149
|
-
marginTop: idx === 0 ? 1 : 0,
|
|
23150
|
-
paddingLeft: 2,
|
|
23151
|
-
flexShrink: 0,
|
|
23152
|
-
children: /* @__PURE__ */ jsx17(Text25, { dimColor: true, children: line })
|
|
23153
|
-
},
|
|
23154
|
-
`req-body-${idx}`
|
|
23155
|
-
));
|
|
23156
|
-
} catch {
|
|
23157
|
-
return /* @__PURE__ */ jsx17(Box28, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx17(Text25, { dimColor: true, children: request.requestBody }) });
|
|
23158
|
-
}
|
|
23159
|
-
})()
|
|
24248
|
+
request.requestBody && /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24249
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx18(Text26, { bold: true, children: "Request Body:" }) }),
|
|
24250
|
+
/* @__PURE__ */ jsx18(BodyLines, { body: request.requestBody, keyPrefix: "req-body" })
|
|
23160
24251
|
] }),
|
|
23161
|
-
request.responseHeaders && Object.keys(request.responseHeaders).length > 0 && /* @__PURE__ */
|
|
23162
|
-
/* @__PURE__ */
|
|
23163
|
-
Object.entries(request.responseHeaders).map(([key, value]) => /* @__PURE__ */
|
|
24252
|
+
request.responseHeaders && Object.keys(request.responseHeaders).length > 0 && /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24253
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx18(Text26, { bold: true, children: "Response Headers:" }) }),
|
|
24254
|
+
Object.entries(request.responseHeaders).map(([key, value]) => /* @__PURE__ */ jsx18(Box29, { marginTop: 0, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23164
24255
|
key,
|
|
23165
24256
|
": ",
|
|
23166
24257
|
value
|
|
23167
24258
|
] }) }, key))
|
|
23168
24259
|
] }),
|
|
23169
|
-
request.responseBody && /* @__PURE__ */
|
|
23170
|
-
/* @__PURE__ */
|
|
23171
|
-
(
|
|
23172
|
-
try {
|
|
23173
|
-
const parsed = JSON.parse(request.responseBody);
|
|
23174
|
-
return JSON.stringify(parsed, null, 2).split("\n").map((line, idx) => /* @__PURE__ */ jsx17(
|
|
23175
|
-
Box28,
|
|
23176
|
-
{
|
|
23177
|
-
marginTop: idx === 0 ? 1 : 0,
|
|
23178
|
-
paddingLeft: 2,
|
|
23179
|
-
flexShrink: 0,
|
|
23180
|
-
children: /* @__PURE__ */ jsx17(Text25, { dimColor: true, children: line })
|
|
23181
|
-
},
|
|
23182
|
-
`resp-body-${idx}`
|
|
23183
|
-
));
|
|
23184
|
-
} catch {
|
|
23185
|
-
return /* @__PURE__ */ jsx17(Box28, { marginTop: 1, paddingLeft: 2, flexShrink: 0, children: /* @__PURE__ */ jsx17(Text25, { dimColor: true, children: request.responseBody }) });
|
|
23186
|
-
}
|
|
23187
|
-
})()
|
|
24260
|
+
request.responseBody && /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24261
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx18(Text26, { bold: true, children: "Response Body:" }) }),
|
|
24262
|
+
/* @__PURE__ */ jsx18(BodyLines, { body: request.responseBody, keyPrefix: "resp-body" })
|
|
23188
24263
|
] })
|
|
23189
24264
|
] });
|
|
23190
|
-
const renderMessageDetails = (message) => /* @__PURE__ */
|
|
23191
|
-
/* @__PURE__ */
|
|
24265
|
+
const renderMessageDetails = (message) => /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24266
|
+
/* @__PURE__ */ jsx18(Box29, { flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { bold: true, children: [
|
|
23192
24267
|
"Direction: ",
|
|
23193
24268
|
message.direction
|
|
23194
24269
|
] }) }),
|
|
23195
|
-
/* @__PURE__ */
|
|
24270
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23196
24271
|
message.timestamp.toLocaleTimeString(),
|
|
23197
24272
|
message.duration !== void 0 && ` (${message.duration}ms)`
|
|
23198
24273
|
] }) }),
|
|
23199
|
-
message.direction === "request" ? /* @__PURE__ */
|
|
23200
|
-
/* @__PURE__ */
|
|
23201
|
-
/* @__PURE__ */
|
|
23202
|
-
/* @__PURE__ */
|
|
24274
|
+
message.direction === "request" ? /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24275
|
+
/* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24276
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Request:" }),
|
|
24277
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(message.message, null, 2) }) })
|
|
23203
24278
|
] }),
|
|
23204
|
-
message.response && /* @__PURE__ */
|
|
23205
|
-
/* @__PURE__ */
|
|
23206
|
-
/* @__PURE__ */
|
|
24279
|
+
message.response && /* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24280
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: "Response:" }),
|
|
24281
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(message.response, null, 2) }) })
|
|
23207
24282
|
] })
|
|
23208
|
-
] }) : /* @__PURE__ */
|
|
23209
|
-
/* @__PURE__ */
|
|
23210
|
-
/* @__PURE__ */
|
|
24283
|
+
] }) : /* @__PURE__ */ jsxs17(Box29, { marginTop: 1, flexShrink: 0, flexDirection: "column", children: [
|
|
24284
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, children: message.direction === "response" ? "Response:" : "Notification:" }),
|
|
24285
|
+
/* @__PURE__ */ jsx18(Box29, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: JSON.stringify(message.message, null, 2) }) })
|
|
23211
24286
|
] })
|
|
23212
24287
|
] });
|
|
23213
24288
|
useEffect14(() => {
|
|
@@ -23398,15 +24473,15 @@ function App({
|
|
|
23398
24473
|
return "\u25CB";
|
|
23399
24474
|
}
|
|
23400
24475
|
};
|
|
23401
|
-
return /* @__PURE__ */
|
|
23402
|
-
|
|
24476
|
+
return /* @__PURE__ */ jsxs17(
|
|
24477
|
+
Box29,
|
|
23403
24478
|
{
|
|
23404
24479
|
flexDirection: "column",
|
|
23405
24480
|
width: dimensions.width,
|
|
23406
24481
|
height: dimensions.height,
|
|
23407
24482
|
children: [
|
|
23408
|
-
/* @__PURE__ */
|
|
23409
|
-
|
|
24483
|
+
/* @__PURE__ */ jsxs17(
|
|
24484
|
+
Box29,
|
|
23410
24485
|
{
|
|
23411
24486
|
width: dimensions.width,
|
|
23412
24487
|
height: headerHeight,
|
|
@@ -23418,29 +24493,29 @@ function App({
|
|
|
23418
24493
|
justifyContent: "space-between",
|
|
23419
24494
|
alignItems: "center",
|
|
23420
24495
|
children: [
|
|
23421
|
-
/* @__PURE__ */
|
|
23422
|
-
/* @__PURE__ */
|
|
23423
|
-
/* @__PURE__ */
|
|
24496
|
+
/* @__PURE__ */ jsxs17(Box29, { children: [
|
|
24497
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, color: "cyan", children: APP_NAME }),
|
|
24498
|
+
/* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23424
24499
|
" - ",
|
|
23425
24500
|
APP_DESCRIPTION
|
|
23426
24501
|
] })
|
|
23427
24502
|
] }),
|
|
23428
|
-
/* @__PURE__ */
|
|
24503
|
+
/* @__PURE__ */ jsxs17(Text26, { dimColor: true, children: [
|
|
23429
24504
|
"v",
|
|
23430
24505
|
APP_VERSION
|
|
23431
24506
|
] })
|
|
23432
24507
|
]
|
|
23433
24508
|
}
|
|
23434
24509
|
),
|
|
23435
|
-
/* @__PURE__ */
|
|
23436
|
-
|
|
24510
|
+
/* @__PURE__ */ jsxs17(
|
|
24511
|
+
Box29,
|
|
23437
24512
|
{
|
|
23438
24513
|
flexDirection: "row",
|
|
23439
24514
|
height: availableHeight + tabsHeight,
|
|
23440
24515
|
width: dimensions.width,
|
|
23441
24516
|
children: [
|
|
23442
|
-
/* @__PURE__ */
|
|
23443
|
-
|
|
24517
|
+
/* @__PURE__ */ jsxs17(
|
|
24518
|
+
Box29,
|
|
23444
24519
|
{
|
|
23445
24520
|
width: serverListWidth,
|
|
23446
24521
|
height: availableHeight + tabsHeight,
|
|
@@ -23452,43 +24527,43 @@ function App({
|
|
|
23452
24527
|
flexDirection: "column",
|
|
23453
24528
|
paddingX: 1,
|
|
23454
24529
|
children: [
|
|
23455
|
-
/* @__PURE__ */
|
|
23456
|
-
|
|
24530
|
+
/* @__PURE__ */ jsx18(Box29, { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx18(
|
|
24531
|
+
Text26,
|
|
23457
24532
|
{
|
|
23458
24533
|
bold: true,
|
|
23459
24534
|
backgroundColor: focus === "serverList" ? "yellow" : void 0,
|
|
23460
24535
|
children: "MCP Servers"
|
|
23461
24536
|
}
|
|
23462
24537
|
) }),
|
|
23463
|
-
/* @__PURE__ */
|
|
24538
|
+
/* @__PURE__ */ jsx18(Box29, { flexDirection: "column", flexGrow: 1, children: serverNames.map((serverName) => {
|
|
23464
24539
|
const isSelected = selectedServer === serverName;
|
|
23465
|
-
return /* @__PURE__ */
|
|
24540
|
+
return /* @__PURE__ */ jsx18(Box29, { paddingY: 0, children: /* @__PURE__ */ jsxs17(Text26, { children: [
|
|
23466
24541
|
isSelected ? "\u25B6 " : " ",
|
|
23467
24542
|
serverName
|
|
23468
24543
|
] }) }, serverName);
|
|
23469
24544
|
}) }),
|
|
23470
|
-
/* @__PURE__ */
|
|
23471
|
-
|
|
24545
|
+
/* @__PURE__ */ jsx18(
|
|
24546
|
+
Box29,
|
|
23472
24547
|
{
|
|
23473
24548
|
flexShrink: 0,
|
|
23474
24549
|
height: 1,
|
|
23475
24550
|
justifyContent: "center",
|
|
23476
24551
|
backgroundColor: "gray",
|
|
23477
|
-
children: /* @__PURE__ */
|
|
24552
|
+
children: /* @__PURE__ */ jsx18(Text26, { bold: true, color: "white", children: "ESC to exit" })
|
|
23478
24553
|
}
|
|
23479
24554
|
)
|
|
23480
24555
|
]
|
|
23481
24556
|
}
|
|
23482
24557
|
),
|
|
23483
|
-
/* @__PURE__ */
|
|
23484
|
-
|
|
24558
|
+
/* @__PURE__ */ jsxs17(
|
|
24559
|
+
Box29,
|
|
23485
24560
|
{
|
|
23486
24561
|
flexGrow: 1,
|
|
23487
24562
|
height: availableHeight + tabsHeight,
|
|
23488
24563
|
flexDirection: "column",
|
|
23489
24564
|
children: [
|
|
23490
|
-
/* @__PURE__ */
|
|
23491
|
-
|
|
24565
|
+
/* @__PURE__ */ jsx18(
|
|
24566
|
+
Box29,
|
|
23492
24567
|
{
|
|
23493
24568
|
width: contentWidth,
|
|
23494
24569
|
borderStyle: "single",
|
|
@@ -23500,49 +24575,49 @@ function App({
|
|
|
23500
24575
|
paddingY: 1,
|
|
23501
24576
|
flexDirection: "column",
|
|
23502
24577
|
flexShrink: 0,
|
|
23503
|
-
children: /* @__PURE__ */
|
|
23504
|
-
/* @__PURE__ */
|
|
23505
|
-
|
|
24578
|
+
children: /* @__PURE__ */ jsxs17(Box29, { flexDirection: "column", children: [
|
|
24579
|
+
/* @__PURE__ */ jsxs17(
|
|
24580
|
+
Box29,
|
|
23506
24581
|
{
|
|
23507
24582
|
flexDirection: "row",
|
|
23508
24583
|
justifyContent: "space-between",
|
|
23509
24584
|
alignItems: "center",
|
|
23510
24585
|
children: [
|
|
23511
|
-
/* @__PURE__ */
|
|
23512
|
-
/* @__PURE__ */
|
|
23513
|
-
/* @__PURE__ */
|
|
24586
|
+
/* @__PURE__ */ jsx18(Text26, { bold: true, color: "cyan", children: selectedServer }),
|
|
24587
|
+
/* @__PURE__ */ jsx18(Box29, { flexDirection: "row", alignItems: "center", gap: 1, children: currentServerState && /* @__PURE__ */ jsxs17(Fragment13, { children: [
|
|
24588
|
+
/* @__PURE__ */ jsxs17(Text26, { color: getStatusColor(currentServerState.status), children: [
|
|
23514
24589
|
getStatusSymbol(currentServerState.status),
|
|
23515
24590
|
" ",
|
|
23516
24591
|
currentServerState.status
|
|
23517
24592
|
] }),
|
|
23518
|
-
/* @__PURE__ */
|
|
23519
|
-
(currentServerState?.status === "disconnected" || currentServerState?.status === "error") && /* @__PURE__ */
|
|
24593
|
+
/* @__PURE__ */ jsx18(Text26, { children: " " }),
|
|
24594
|
+
(currentServerState?.status === "disconnected" || currentServerState?.status === "error") && /* @__PURE__ */ jsxs17(Text26, { color: "cyan", bold: true, children: [
|
|
23520
24595
|
"[",
|
|
23521
|
-
/* @__PURE__ */
|
|
24596
|
+
/* @__PURE__ */ jsx18(Text26, { underline: true, children: "C" }),
|
|
23522
24597
|
"onnect]"
|
|
23523
24598
|
] }),
|
|
23524
|
-
(currentServerState?.status === "connected" || currentServerState?.status === "connecting") && /* @__PURE__ */
|
|
24599
|
+
(currentServerState?.status === "connected" || currentServerState?.status === "connecting") && /* @__PURE__ */ jsxs17(Text26, { color: "red", bold: true, children: [
|
|
23525
24600
|
"[",
|
|
23526
|
-
/* @__PURE__ */
|
|
24601
|
+
/* @__PURE__ */ jsx18(Text26, { underline: true, children: "D" }),
|
|
23527
24602
|
"isconnect]"
|
|
23528
24603
|
] })
|
|
23529
24604
|
] }) })
|
|
23530
24605
|
]
|
|
23531
24606
|
}
|
|
23532
24607
|
),
|
|
23533
|
-
oauthStatus === "authenticating" && /* @__PURE__ */
|
|
23534
|
-
oauthStatus === "error" && oauthMessage && /* @__PURE__ */
|
|
24608
|
+
oauthStatus === "authenticating" && /* @__PURE__ */ jsx18(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx18(Text26, { dimColor: true, children: "OAuth: authenticating\u2026" }) }),
|
|
24609
|
+
oauthStatus === "error" && oauthMessage && /* @__PURE__ */ jsx18(Box29, { marginTop: 1, children: /* @__PURE__ */ jsxs17(Text26, { color: "red", children: [
|
|
23535
24610
|
"OAuth: ",
|
|
23536
24611
|
oauthMessage
|
|
23537
24612
|
] }) }),
|
|
23538
|
-
disconnectError && /* @__PURE__ */
|
|
24613
|
+
disconnectError && /* @__PURE__ */ jsx18(Box29, { marginTop: 1, children: /* @__PURE__ */ jsxs17(Text26, { color: "red", children: [
|
|
23539
24614
|
"Disconnect failed: ",
|
|
23540
24615
|
disconnectError
|
|
23541
24616
|
] }) })
|
|
23542
24617
|
] })
|
|
23543
24618
|
}
|
|
23544
24619
|
),
|
|
23545
|
-
/* @__PURE__ */
|
|
24620
|
+
/* @__PURE__ */ jsx18(
|
|
23546
24621
|
Tabs,
|
|
23547
24622
|
{
|
|
23548
24623
|
activeTab,
|
|
@@ -23559,8 +24634,8 @@ function App({
|
|
|
23559
24634
|
})() : false
|
|
23560
24635
|
}
|
|
23561
24636
|
),
|
|
23562
|
-
/* @__PURE__ */
|
|
23563
|
-
|
|
24637
|
+
/* @__PURE__ */ jsxs17(
|
|
24638
|
+
Box29,
|
|
23564
24639
|
{
|
|
23565
24640
|
flexGrow: 1,
|
|
23566
24641
|
minHeight: 6,
|
|
@@ -23570,7 +24645,7 @@ function App({
|
|
|
23570
24645
|
borderRight: false,
|
|
23571
24646
|
borderBottom: false,
|
|
23572
24647
|
children: [
|
|
23573
|
-
activeTab === "info" && /* @__PURE__ */
|
|
24648
|
+
activeTab === "info" && /* @__PURE__ */ jsx18(
|
|
23574
24649
|
InfoTab,
|
|
23575
24650
|
{
|
|
23576
24651
|
serverName: selectedServer,
|
|
@@ -23582,7 +24657,7 @@ function App({
|
|
|
23582
24657
|
focused: focus === "tabContentList" || focus === "tabContentDetails"
|
|
23583
24658
|
}
|
|
23584
24659
|
),
|
|
23585
|
-
activeTab === "auth" && selectedServer && selectedServerConfig && isOAuthCapableServerConfig(selectedServerConfig) ? /* @__PURE__ */
|
|
24660
|
+
activeTab === "auth" && selectedServer && selectedServerConfig && isOAuthCapableServerConfig(selectedServerConfig) ? /* @__PURE__ */ jsx18(
|
|
23586
24661
|
AuthTab,
|
|
23587
24662
|
{
|
|
23588
24663
|
serverName: selectedServer,
|
|
@@ -23680,7 +24755,7 @@ function App({
|
|
|
23680
24755
|
connectionStatus: inspectorStatus
|
|
23681
24756
|
}
|
|
23682
24757
|
) : null,
|
|
23683
|
-
activeTab === "resources" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */
|
|
24758
|
+
activeTab === "resources" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */ jsx18(
|
|
23684
24759
|
ResourcesTab,
|
|
23685
24760
|
{
|
|
23686
24761
|
resources: currentServerState.resources,
|
|
@@ -23706,7 +24781,7 @@ function App({
|
|
|
23706
24781
|
modalOpen: !!(toolTestModal || resourceTestModal || promptTestModal || detailsModal)
|
|
23707
24782
|
},
|
|
23708
24783
|
`resources-${selectedServer}`
|
|
23709
|
-
) : activeTab === "skills" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */
|
|
24784
|
+
) : activeTab === "skills" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */ jsx18(
|
|
23710
24785
|
SkillsTab,
|
|
23711
24786
|
{
|
|
23712
24787
|
skills: managedSkills,
|
|
@@ -23720,7 +24795,7 @@ function App({
|
|
|
23720
24795
|
modalOpen: !!(toolTestModal || resourceTestModal || promptTestModal || detailsModal)
|
|
23721
24796
|
},
|
|
23722
24797
|
`skills-${selectedServer}`
|
|
23723
|
-
) : activeTab === "prompts" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */
|
|
24798
|
+
) : activeTab === "prompts" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */ jsx18(
|
|
23724
24799
|
PromptsTab,
|
|
23725
24800
|
{
|
|
23726
24801
|
prompts: currentServerState.prompts,
|
|
@@ -23743,7 +24818,7 @@ function App({
|
|
|
23743
24818
|
modalOpen: !!(toolTestModal || resourceTestModal || promptTestModal || detailsModal)
|
|
23744
24819
|
},
|
|
23745
24820
|
`prompts-${selectedServer}`
|
|
23746
|
-
) : activeTab === "tools" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */
|
|
24821
|
+
) : activeTab === "tools" && currentServerState?.status === "connected" && selectedInspectorClient ? /* @__PURE__ */ jsx18(
|
|
23747
24822
|
ToolsTab,
|
|
23748
24823
|
{
|
|
23749
24824
|
tools: currentServerState.tools,
|
|
@@ -23763,7 +24838,7 @@ function App({
|
|
|
23763
24838
|
modalOpen: !!(toolTestModal || detailsModal)
|
|
23764
24839
|
},
|
|
23765
24840
|
`tools-${selectedServer}`
|
|
23766
|
-
) : activeTab === "messages" && selectedInspectorClient ? /* @__PURE__ */
|
|
24841
|
+
) : activeTab === "messages" && selectedInspectorClient ? /* @__PURE__ */ jsx18(
|
|
23767
24842
|
HistoryTab,
|
|
23768
24843
|
{
|
|
23769
24844
|
serverName: selectedServer,
|
|
@@ -23781,7 +24856,7 @@ function App({
|
|
|
23781
24856
|
});
|
|
23782
24857
|
}
|
|
23783
24858
|
}
|
|
23784
|
-
) : activeTab === "requests" && selectedInspectorClient && (inspectorStatus === "connected" || inspectorFetchRequests.length > 0) ? /* @__PURE__ */
|
|
24859
|
+
) : activeTab === "requests" && selectedInspectorClient && (inspectorStatus === "connected" || inspectorFetchRequests.length > 0) ? /* @__PURE__ */ jsx18(
|
|
23785
24860
|
RequestsTab,
|
|
23786
24861
|
{
|
|
23787
24862
|
serverName: selectedServer,
|
|
@@ -23798,7 +24873,7 @@ function App({
|
|
|
23798
24873
|
});
|
|
23799
24874
|
}
|
|
23800
24875
|
}
|
|
23801
|
-
) : activeTab === "logging" && selectedInspectorClient ? /* @__PURE__ */
|
|
24876
|
+
) : activeTab === "logging" && selectedInspectorClient ? /* @__PURE__ */ jsx18(
|
|
23802
24877
|
NotificationsTab,
|
|
23803
24878
|
{
|
|
23804
24879
|
stderrLogs: inspectorStderrLogs,
|
|
@@ -23817,7 +24892,7 @@ function App({
|
|
|
23817
24892
|
]
|
|
23818
24893
|
}
|
|
23819
24894
|
),
|
|
23820
|
-
toolTestModal && /* @__PURE__ */
|
|
24895
|
+
toolTestModal && /* @__PURE__ */ jsx18(
|
|
23821
24896
|
ToolTestModal,
|
|
23822
24897
|
{
|
|
23823
24898
|
tool: toolTestModal.tool,
|
|
@@ -23831,7 +24906,7 @@ function App({
|
|
|
23831
24906
|
}
|
|
23832
24907
|
}
|
|
23833
24908
|
),
|
|
23834
|
-
resourceTestModal && /* @__PURE__ */
|
|
24909
|
+
resourceTestModal && /* @__PURE__ */ jsx18(
|
|
23835
24910
|
ResourceTestModal,
|
|
23836
24911
|
{
|
|
23837
24912
|
template: resourceTestModal.template,
|
|
@@ -23845,7 +24920,7 @@ function App({
|
|
|
23845
24920
|
}
|
|
23846
24921
|
}
|
|
23847
24922
|
),
|
|
23848
|
-
promptTestModal && /* @__PURE__ */
|
|
24923
|
+
promptTestModal && /* @__PURE__ */ jsx18(
|
|
23849
24924
|
PromptTestModal,
|
|
23850
24925
|
{
|
|
23851
24926
|
prompt: promptTestModal.prompt,
|
|
@@ -23859,7 +24934,7 @@ function App({
|
|
|
23859
24934
|
}
|
|
23860
24935
|
}
|
|
23861
24936
|
),
|
|
23862
|
-
detailsModal && /* @__PURE__ */
|
|
24937
|
+
detailsModal && /* @__PURE__ */ jsx18(
|
|
23863
24938
|
DetailsModal,
|
|
23864
24939
|
{
|
|
23865
24940
|
title: detailsModal.title,
|
|
@@ -23876,7 +24951,7 @@ function App({
|
|
|
23876
24951
|
var App_default = App;
|
|
23877
24952
|
|
|
23878
24953
|
// tui.tsx
|
|
23879
|
-
import { jsx as
|
|
24954
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
23880
24955
|
async function runTui(args) {
|
|
23881
24956
|
const program = new Command();
|
|
23882
24957
|
program.name("mcp-inspector-tui").description("Terminal UI for MCP Inspector").option(
|
|
@@ -23965,7 +25040,7 @@ async function runTui(args) {
|
|
|
23965
25040
|
process.stdout.write("\x1B[?1049h");
|
|
23966
25041
|
}
|
|
23967
25042
|
const instance = render2(
|
|
23968
|
-
/* @__PURE__ */
|
|
25043
|
+
/* @__PURE__ */ jsx19(
|
|
23969
25044
|
App_default,
|
|
23970
25045
|
{
|
|
23971
25046
|
mcpServers,
|