@modelcontextprotocol/inspector-client 0.16.2 → 0.16.4

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/bin/start.js CHANGED
@@ -28,8 +28,15 @@ function getClientUrl(port, authDisabled, sessionToken, serverPort) {
28
28
  }
29
29
 
30
30
  async function startDevServer(serverOptions) {
31
- const { SERVER_PORT, CLIENT_PORT, sessionToken, envVars, abort } =
32
- serverOptions;
31
+ const {
32
+ SERVER_PORT,
33
+ CLIENT_PORT,
34
+ sessionToken,
35
+ envVars,
36
+ abort,
37
+ transport,
38
+ serverUrl,
39
+ } = serverOptions;
33
40
  const serverCommand = "npx";
34
41
  const serverArgs = ["tsx", "watch", "--clear-screen=false", "src/index.ts"];
35
42
  const isWindows = process.platform === "win32";
@@ -42,6 +49,8 @@ async function startDevServer(serverOptions) {
42
49
  CLIENT_PORT,
43
50
  MCP_PROXY_AUTH_TOKEN: sessionToken,
44
51
  MCP_ENV_VARS: JSON.stringify(envVars),
52
+ ...(transport ? { MCP_TRANSPORT: transport } : {}),
53
+ ...(serverUrl ? { MCP_SERVER_URL: serverUrl } : {}),
45
54
  },
46
55
  signal: abort.signal,
47
56
  echoOutput: true,
@@ -78,6 +87,8 @@ async function startProdServer(serverOptions) {
78
87
  abort,
79
88
  command,
80
89
  mcpServerArgs,
90
+ transport,
91
+ serverUrl,
81
92
  } = serverOptions;
82
93
  const inspectorServerPath = resolve(
83
94
  __dirname,
@@ -91,10 +102,12 @@ async function startProdServer(serverOptions) {
91
102
  "node",
92
103
  [
93
104
  inspectorServerPath,
94
- ...(command ? [`--command`, command] : []),
105
+ ...(command ? [`--command=${command}`] : []),
95
106
  ...(mcpServerArgs && mcpServerArgs.length > 0
96
- ? [`--args`, mcpServerArgs.join(" ")]
107
+ ? [`--args=${mcpServerArgs.join(" ")}`]
97
108
  : []),
109
+ ...(transport ? [`--transport=${transport}`] : []),
110
+ ...(serverUrl ? [`--server-url=${serverUrl}`] : []),
98
111
  ],
99
112
  {
100
113
  env: {
@@ -208,6 +221,8 @@ async function main() {
208
221
  let command = null;
209
222
  let parsingFlags = true;
210
223
  let isDev = false;
224
+ let transport = null;
225
+ let serverUrl = null;
211
226
 
212
227
  for (let i = 0; i < args.length; i++) {
213
228
  const arg = args[i];
@@ -222,6 +237,16 @@ async function main() {
222
237
  continue;
223
238
  }
224
239
 
240
+ if (parsingFlags && arg === "--transport" && i + 1 < args.length) {
241
+ transport = args[++i];
242
+ continue;
243
+ }
244
+
245
+ if (parsingFlags && arg === "--server-url" && i + 1 < args.length) {
246
+ serverUrl = args[++i];
247
+ continue;
248
+ }
249
+
225
250
  if (parsingFlags && arg === "-e" && i + 1 < args.length) {
226
251
  const envVar = args[++i];
227
252
  const equalsIndex = envVar.indexOf("=");
@@ -273,6 +298,8 @@ async function main() {
273
298
  abort,
274
299
  command,
275
300
  mcpServerArgs,
301
+ transport,
302
+ serverUrl,
276
303
  };
277
304
 
278
305
  const result = isDev
@@ -1,5 +1,4 @@
1
- import { u as useToast, r as reactExports, j as jsxRuntimeExports, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-DLtnCiTW.js";
2
- import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
1
+ import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-MFoeZZBS.js";
3
2
  const OAuthCallback = ({ onConnect }) => {
4
3
  const { toast } = useToast();
5
4
  const hasProcessedRef = reactExports.useRef(false);
@@ -1,5 +1,4 @@
1
- import { r as reactExports, S as SESSION_KEYS, j as jsxRuntimeExports } from "./index-DLtnCiTW.js";
2
- import { p as parseOAuthCallbackParams, g as generateOAuthErrorDescription } from "./oauthUtils-DTcoXpSP.js";
1
+ import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-MFoeZZBS.js";
3
2
  const OAuthDebugCallback = ({ onConnect }) => {
4
3
  reactExports.useEffect(() => {
5
4
  let isProcessed = false;
@@ -56,8 +56,6 @@ pre[class*="language-"] {
56
56
  -moz-tab-size: 4;
57
57
  -o-tab-size: 4;
58
58
  tab-size: 4;
59
-
60
- -webkit-hyphens: none;
61
59
  hyphens: none;
62
60
  }
63
61
 
@@ -1631,9 +1629,7 @@ video {
1631
1629
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
1632
1630
  }
1633
1631
  .transition {
1634
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
1635
1632
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1636
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
1637
1633
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1638
1634
  transition-duration: 150ms;
1639
1635
  }
@@ -1,4 +1,3 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/OAuthCallback-CC1cu0Zx.js","assets/oauthUtils-DTcoXpSP.js","assets/OAuthDebugCallback-_4BLxVDe.js"])))=>i.map(i=>d[i]);
2
1
  function _mergeNamespaces(n, m2) {
3
2
  for (var i = 0; i < m2.length; i++) {
4
3
  const e = m2[i];
@@ -1123,13 +1122,13 @@ function requireReactDom_production_min() {
1123
1122
  function lb(a, b) {
1124
1123
  return null == a || "http://www.w3.org/1999/xhtml" === a ? kb(b) : "http://www.w3.org/2000/svg" === a && "foreignObject" === b ? "http://www.w3.org/1999/xhtml" : a;
1125
1124
  }
1126
- var mb, nb = function(a) {
1125
+ var mb, nb = (function(a) {
1127
1126
  return "undefined" !== typeof MSApp && MSApp.execUnsafeLocalFunction ? function(b, c, d, e) {
1128
1127
  MSApp.execUnsafeLocalFunction(function() {
1129
1128
  return a(b, c, d, e);
1130
1129
  });
1131
1130
  } : a;
1132
- }(function(a, b) {
1131
+ })(function(a, b) {
1133
1132
  if ("http://www.w3.org/2000/svg" !== a.namespaceURI || "innerHTML" in a) a.innerHTML = b;
1134
1133
  else {
1135
1134
  mb = mb || document.createElement("div");
@@ -7809,7 +7808,7 @@ function usePresence(present) {
7809
7808
  const ownerWindow = node.ownerDocument.defaultView ?? window;
7810
7809
  const handleAnimationEnd = (event) => {
7811
7810
  const currentAnimationName = getAnimationName(stylesRef.current);
7812
- const isCurrentAnimation = currentAnimationName.includes(event.animationName);
7811
+ const isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName));
7813
7812
  if (event.target === node && isCurrentAnimation) {
7814
7813
  send("ANIMATION_END");
7815
7814
  if (!prevPresentRef.current) {
@@ -8163,7 +8162,6 @@ var FocusProxy = reactExports.forwardRef(
8163
8162
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
8164
8163
  VisuallyHidden,
8165
8164
  {
8166
- "aria-hidden": true,
8167
8165
  tabIndex: 0,
8168
8166
  ...proxyProps,
8169
8167
  ref: forwardedRef,
@@ -8317,7 +8315,6 @@ var ToastImpl = reactExports.forwardRef(
8317
8315
  __scopeToast,
8318
8316
  role: "status",
8319
8317
  "aria-live": type2 === "foreground" ? "assertive" : "polite",
8320
- "aria-atomic": true,
8321
8318
  children: announceTextContent
8322
8319
  }
8323
8320
  ),
@@ -8333,9 +8330,6 @@ var ToastImpl = reactExports.forwardRef(
8333
8330
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8334
8331
  Primitive.li,
8335
8332
  {
8336
- role: "status",
8337
- "aria-live": "off",
8338
- "aria-atomic": true,
8339
8333
  tabIndex: 0,
8340
8334
  "data-state": open ? "open" : "closed",
8341
8335
  "data-swipe-direction": context.swipeDirection,
@@ -16258,155 +16252,10 @@ const EMPTY_DEBUGGER_STATE = {
16258
16252
  statusMessage: null,
16259
16253
  validationError: null
16260
16254
  };
16261
- const getClientInformationFromSessionStorage = async ({
16262
- serverUrl,
16263
- isPreregistered
16264
- }) => {
16265
- const key = getServerSpecificKey(
16266
- isPreregistered ? SESSION_KEYS.PREREGISTERED_CLIENT_INFORMATION : SESSION_KEYS.CLIENT_INFORMATION,
16267
- serverUrl
16268
- );
16269
- const value = sessionStorage.getItem(key);
16270
- if (!value) {
16271
- return void 0;
16272
- }
16273
- return await OAuthClientInformationSchema.parseAsync(JSON.parse(value));
16274
- };
16275
- const saveClientInformationToSessionStorage = ({
16276
- serverUrl,
16277
- clientInformation,
16278
- isPreregistered
16279
- }) => {
16280
- const key = getServerSpecificKey(
16281
- isPreregistered ? SESSION_KEYS.PREREGISTERED_CLIENT_INFORMATION : SESSION_KEYS.CLIENT_INFORMATION,
16282
- serverUrl
16283
- );
16284
- sessionStorage.setItem(key, JSON.stringify(clientInformation));
16285
- };
16286
- const clearClientInformationFromSessionStorage = ({
16287
- serverUrl,
16288
- isPreregistered
16289
- }) => {
16290
- const key = getServerSpecificKey(
16291
- isPreregistered ? SESSION_KEYS.PREREGISTERED_CLIENT_INFORMATION : SESSION_KEYS.CLIENT_INFORMATION,
16292
- serverUrl
16293
- );
16294
- sessionStorage.removeItem(key);
16295
- };
16296
- class InspectorOAuthClientProvider {
16297
- constructor(serverUrl) {
16298
- this.serverUrl = serverUrl;
16299
- sessionStorage.setItem(SESSION_KEYS.SERVER_URL, serverUrl);
16300
- }
16301
- get redirectUrl() {
16302
- return window.location.origin + "/oauth/callback";
16303
- }
16304
- get clientMetadata() {
16305
- return {
16306
- redirect_uris: [this.redirectUrl],
16307
- token_endpoint_auth_method: "none",
16308
- grant_types: ["authorization_code", "refresh_token"],
16309
- response_types: ["code"],
16310
- client_name: "MCP Inspector",
16311
- client_uri: "https://github.com/modelcontextprotocol/inspector"
16312
- };
16313
- }
16314
- async clientInformation() {
16315
- const preregisteredClientInformation = await getClientInformationFromSessionStorage({
16316
- serverUrl: this.serverUrl,
16317
- isPreregistered: true
16318
- });
16319
- return preregisteredClientInformation ?? await getClientInformationFromSessionStorage({
16320
- serverUrl: this.serverUrl,
16321
- isPreregistered: false
16322
- });
16323
- }
16324
- saveClientInformation(clientInformation) {
16325
- saveClientInformationToSessionStorage({
16326
- serverUrl: this.serverUrl,
16327
- clientInformation,
16328
- isPreregistered: false
16329
- });
16330
- }
16331
- async tokens() {
16332
- const key = getServerSpecificKey(SESSION_KEYS.TOKENS, this.serverUrl);
16333
- const tokens = sessionStorage.getItem(key);
16334
- if (!tokens) {
16335
- return void 0;
16336
- }
16337
- return await OAuthTokensSchema.parseAsync(JSON.parse(tokens));
16338
- }
16339
- saveTokens(tokens) {
16340
- const key = getServerSpecificKey(SESSION_KEYS.TOKENS, this.serverUrl);
16341
- sessionStorage.setItem(key, JSON.stringify(tokens));
16342
- }
16343
- redirectToAuthorization(authorizationUrl) {
16344
- window.location.href = authorizationUrl.href;
16345
- }
16346
- saveCodeVerifier(codeVerifier) {
16347
- const key = getServerSpecificKey(
16348
- SESSION_KEYS.CODE_VERIFIER,
16349
- this.serverUrl
16350
- );
16351
- sessionStorage.setItem(key, codeVerifier);
16352
- }
16353
- codeVerifier() {
16354
- const key = getServerSpecificKey(
16355
- SESSION_KEYS.CODE_VERIFIER,
16356
- this.serverUrl
16357
- );
16358
- const verifier = sessionStorage.getItem(key);
16359
- if (!verifier) {
16360
- throw new Error("No code verifier saved for session");
16361
- }
16362
- return verifier;
16363
- }
16364
- clear() {
16365
- clearClientInformationFromSessionStorage({
16366
- serverUrl: this.serverUrl,
16367
- isPreregistered: false
16368
- });
16369
- sessionStorage.removeItem(
16370
- getServerSpecificKey(SESSION_KEYS.TOKENS, this.serverUrl)
16371
- );
16372
- sessionStorage.removeItem(
16373
- getServerSpecificKey(SESSION_KEYS.CODE_VERIFIER, this.serverUrl)
16374
- );
16375
- }
16376
- }
16377
- class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvider {
16378
- get redirectUrl() {
16379
- return `${window.location.origin}/oauth/callback/debug`;
16380
- }
16381
- saveServerMetadata(metadata) {
16382
- const key = getServerSpecificKey(
16383
- SESSION_KEYS.SERVER_METADATA,
16384
- this.serverUrl
16385
- );
16386
- sessionStorage.setItem(key, JSON.stringify(metadata));
16387
- }
16388
- getServerMetadata() {
16389
- const key = getServerSpecificKey(
16390
- SESSION_KEYS.SERVER_METADATA,
16391
- this.serverUrl
16392
- );
16393
- const metadata = sessionStorage.getItem(key);
16394
- if (!metadata) {
16395
- return null;
16396
- }
16397
- return JSON.parse(metadata);
16398
- }
16399
- clear() {
16400
- super.clear();
16401
- sessionStorage.removeItem(
16402
- getServerSpecificKey(SESSION_KEYS.SERVER_METADATA, this.serverUrl)
16403
- );
16404
- }
16405
- }
16406
- let crypto;
16407
- crypto = globalThis.crypto;
16255
+ let crypto$1;
16256
+ crypto$1 = globalThis.crypto;
16408
16257
  async function getRandomValues(size2) {
16409
- return (await crypto).getRandomValues(new Uint8Array(size2));
16258
+ return (await crypto$1).getRandomValues(new Uint8Array(size2));
16410
16259
  }
16411
16260
  async function random(size2) {
16412
16261
  const mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";
@@ -16422,7 +16271,7 @@ async function generateVerifier(length) {
16422
16271
  return await random(length);
16423
16272
  }
16424
16273
  async function generateChallenge(code_verifier) {
16425
- const buffer = await (await crypto).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
16274
+ const buffer = await (await crypto$1).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
16426
16275
  return btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
16427
16276
  }
16428
16277
  async function pkceChallenge(length) {
@@ -16653,7 +16502,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
16653
16502
  }
16654
16503
  const fullInformation = await registerClient(authorizationServerUrl, {
16655
16504
  metadata,
16656
- clientMetadata: provider.clientMetadata
16505
+ clientMetadata: provider.clientMetadata,
16506
+ fetchFn
16657
16507
  });
16658
16508
  await provider.saveClientInformation(fullInformation);
16659
16509
  clientInformation = fullInformation;
@@ -16681,7 +16531,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
16681
16531
  clientInformation,
16682
16532
  refreshToken: tokens.refresh_token,
16683
16533
  resource,
16684
- addClientAuthentication: provider.addClientAuthentication
16534
+ addClientAuthentication: provider.addClientAuthentication,
16535
+ fetchFn
16685
16536
  });
16686
16537
  await provider.saveTokens(newTokens);
16687
16538
  return "AUTHORIZED";
@@ -16799,29 +16650,6 @@ async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, o
16799
16650
  }
16800
16651
  return response;
16801
16652
  }
16802
- async function discoverOAuthMetadata(issuer, { authorizationServerUrl, protocolVersion } = {}, fetchFn = fetch) {
16803
- if (typeof issuer === "string") {
16804
- issuer = new URL(issuer);
16805
- }
16806
- if (!authorizationServerUrl) {
16807
- authorizationServerUrl = issuer;
16808
- }
16809
- if (typeof authorizationServerUrl === "string") {
16810
- authorizationServerUrl = new URL(authorizationServerUrl);
16811
- }
16812
- protocolVersion !== null && protocolVersion !== void 0 ? protocolVersion : protocolVersion = LATEST_PROTOCOL_VERSION;
16813
- const response = await discoverMetadataWithFallback(authorizationServerUrl, "oauth-authorization-server", fetchFn, {
16814
- protocolVersion,
16815
- metadataServerUrl: authorizationServerUrl
16816
- });
16817
- if (!response || response.status === 404) {
16818
- return void 0;
16819
- }
16820
- if (!response.ok) {
16821
- throw new Error(`HTTP ${response.status} trying to load well-known OAuth metadata`);
16822
- }
16823
- return OAuthMetadataSchema.parse(await response.json());
16824
- }
16825
16653
  function buildDiscoveryUrls(authorizationServerUrl) {
16826
16654
  const url = typeof authorizationServerUrl === "string" ? new URL(authorizationServerUrl) : authorizationServerUrl;
16827
16655
  const hasPath = url.pathname !== "/";
@@ -16866,7 +16694,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
16866
16694
  for (const { url: endpointUrl, type: type2 } of urlsToTry) {
16867
16695
  const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
16868
16696
  if (!response) {
16869
- throw new Error(`CORS error trying to load ${type2 === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
16697
+ continue;
16870
16698
  }
16871
16699
  if (!response.ok) {
16872
16700
  if (response.status >= 400 && response.status < 500) {
@@ -17021,6 +16849,212 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
17021
16849
  }
17022
16850
  return OAuthClientInformationFullSchema.parse(await response.json());
17023
16851
  }
16852
+ const parseOAuthCallbackParams = (location) => {
16853
+ const params = new URLSearchParams(location);
16854
+ const code = params.get("code");
16855
+ if (code) {
16856
+ return { successful: true, code };
16857
+ }
16858
+ const error = params.get("error");
16859
+ const error_description = params.get("error_description");
16860
+ const error_uri = params.get("error_uri");
16861
+ if (error) {
16862
+ return { successful: false, error, error_description, error_uri };
16863
+ }
16864
+ return {
16865
+ successful: false,
16866
+ error: "invalid_request",
16867
+ error_description: "Missing code or error in response",
16868
+ error_uri: null
16869
+ };
16870
+ };
16871
+ const generateOAuthState = () => {
16872
+ const array = new Uint8Array(32);
16873
+ crypto.getRandomValues(array);
16874
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join(
16875
+ ""
16876
+ );
16877
+ };
16878
+ const generateOAuthErrorDescription = (params) => {
16879
+ const error = params.error;
16880
+ const errorDescription = params.error_description;
16881
+ const errorUri = params.error_uri;
16882
+ return [
16883
+ `Error: ${error}.`,
16884
+ errorDescription ? `Details: ${errorDescription}.` : "",
16885
+ errorUri ? `More info: ${errorUri}.` : ""
16886
+ ].filter(Boolean).join("\n");
16887
+ };
16888
+ const discoverScopes = async (serverUrl, resourceMetadata) => {
16889
+ try {
16890
+ const metadata = await discoverAuthorizationServerMetadata(
16891
+ new URL("/", serverUrl)
16892
+ );
16893
+ const resourceScopes = resourceMetadata == null ? void 0 : resourceMetadata.scopes_supported;
16894
+ const oauthScopes = metadata == null ? void 0 : metadata.scopes_supported;
16895
+ const scopesSupported = resourceScopes && resourceScopes.length > 0 ? resourceScopes : oauthScopes;
16896
+ return scopesSupported && scopesSupported.length > 0 ? scopesSupported.join(" ") : void 0;
16897
+ } catch (error) {
16898
+ console.debug("OAuth scope discovery failed:", error);
16899
+ return void 0;
16900
+ }
16901
+ };
16902
+ const getClientInformationFromSessionStorage = async ({
16903
+ serverUrl,
16904
+ isPreregistered
16905
+ }) => {
16906
+ const key = getServerSpecificKey(
16907
+ isPreregistered ? SESSION_KEYS.PREREGISTERED_CLIENT_INFORMATION : SESSION_KEYS.CLIENT_INFORMATION,
16908
+ serverUrl
16909
+ );
16910
+ const value = sessionStorage.getItem(key);
16911
+ if (!value) {
16912
+ return void 0;
16913
+ }
16914
+ return await OAuthClientInformationSchema.parseAsync(JSON.parse(value));
16915
+ };
16916
+ const saveClientInformationToSessionStorage = ({
16917
+ serverUrl,
16918
+ clientInformation,
16919
+ isPreregistered
16920
+ }) => {
16921
+ const key = getServerSpecificKey(
16922
+ isPreregistered ? SESSION_KEYS.PREREGISTERED_CLIENT_INFORMATION : SESSION_KEYS.CLIENT_INFORMATION,
16923
+ serverUrl
16924
+ );
16925
+ sessionStorage.setItem(key, JSON.stringify(clientInformation));
16926
+ };
16927
+ const clearClientInformationFromSessionStorage = ({
16928
+ serverUrl,
16929
+ isPreregistered
16930
+ }) => {
16931
+ const key = getServerSpecificKey(
16932
+ isPreregistered ? SESSION_KEYS.PREREGISTERED_CLIENT_INFORMATION : SESSION_KEYS.CLIENT_INFORMATION,
16933
+ serverUrl
16934
+ );
16935
+ sessionStorage.removeItem(key);
16936
+ };
16937
+ class InspectorOAuthClientProvider {
16938
+ constructor(serverUrl) {
16939
+ this.serverUrl = serverUrl;
16940
+ sessionStorage.setItem(SESSION_KEYS.SERVER_URL, serverUrl);
16941
+ }
16942
+ get redirectUrl() {
16943
+ return window.location.origin + "/oauth/callback";
16944
+ }
16945
+ get clientMetadata() {
16946
+ return {
16947
+ redirect_uris: [this.redirectUrl],
16948
+ token_endpoint_auth_method: "none",
16949
+ grant_types: ["authorization_code", "refresh_token"],
16950
+ response_types: ["code"],
16951
+ client_name: "MCP Inspector",
16952
+ client_uri: "https://github.com/modelcontextprotocol/inspector"
16953
+ };
16954
+ }
16955
+ state() {
16956
+ return generateOAuthState();
16957
+ }
16958
+ async clientInformation() {
16959
+ const preregisteredClientInformation = await getClientInformationFromSessionStorage({
16960
+ serverUrl: this.serverUrl,
16961
+ isPreregistered: true
16962
+ });
16963
+ return preregisteredClientInformation ?? await getClientInformationFromSessionStorage({
16964
+ serverUrl: this.serverUrl,
16965
+ isPreregistered: false
16966
+ });
16967
+ }
16968
+ saveClientInformation(clientInformation) {
16969
+ const safeInfo = Object.fromEntries(
16970
+ Object.entries(clientInformation).filter(
16971
+ ([key]) => key !== "client_secret"
16972
+ )
16973
+ );
16974
+ saveClientInformationToSessionStorage({
16975
+ serverUrl: this.serverUrl,
16976
+ clientInformation: safeInfo,
16977
+ isPreregistered: false
16978
+ });
16979
+ }
16980
+ async tokens() {
16981
+ const key = getServerSpecificKey(SESSION_KEYS.TOKENS, this.serverUrl);
16982
+ const tokens = sessionStorage.getItem(key);
16983
+ if (!tokens) {
16984
+ return void 0;
16985
+ }
16986
+ return await OAuthTokensSchema.parseAsync(JSON.parse(tokens));
16987
+ }
16988
+ saveTokens(tokens) {
16989
+ const key = getServerSpecificKey(SESSION_KEYS.TOKENS, this.serverUrl);
16990
+ sessionStorage.setItem(key, JSON.stringify(tokens));
16991
+ }
16992
+ redirectToAuthorization(authorizationUrl) {
16993
+ if (authorizationUrl.protocol !== "http:" && authorizationUrl.protocol !== "https:") {
16994
+ throw new Error("Authorization URL must be HTTP or HTTPS");
16995
+ }
16996
+ window.location.href = authorizationUrl.href;
16997
+ }
16998
+ saveCodeVerifier(codeVerifier) {
16999
+ const key = getServerSpecificKey(
17000
+ SESSION_KEYS.CODE_VERIFIER,
17001
+ this.serverUrl
17002
+ );
17003
+ sessionStorage.setItem(key, codeVerifier);
17004
+ }
17005
+ codeVerifier() {
17006
+ const key = getServerSpecificKey(
17007
+ SESSION_KEYS.CODE_VERIFIER,
17008
+ this.serverUrl
17009
+ );
17010
+ const verifier = sessionStorage.getItem(key);
17011
+ if (!verifier) {
17012
+ throw new Error("No code verifier saved for session");
17013
+ }
17014
+ return verifier;
17015
+ }
17016
+ clear() {
17017
+ clearClientInformationFromSessionStorage({
17018
+ serverUrl: this.serverUrl,
17019
+ isPreregistered: false
17020
+ });
17021
+ sessionStorage.removeItem(
17022
+ getServerSpecificKey(SESSION_KEYS.TOKENS, this.serverUrl)
17023
+ );
17024
+ sessionStorage.removeItem(
17025
+ getServerSpecificKey(SESSION_KEYS.CODE_VERIFIER, this.serverUrl)
17026
+ );
17027
+ }
17028
+ }
17029
+ class DebugInspectorOAuthClientProvider extends InspectorOAuthClientProvider {
17030
+ get redirectUrl() {
17031
+ return `${window.location.origin}/oauth/callback/debug`;
17032
+ }
17033
+ saveServerMetadata(metadata) {
17034
+ const key = getServerSpecificKey(
17035
+ SESSION_KEYS.SERVER_METADATA,
17036
+ this.serverUrl
17037
+ );
17038
+ sessionStorage.setItem(key, JSON.stringify(metadata));
17039
+ }
17040
+ getServerMetadata() {
17041
+ const key = getServerSpecificKey(
17042
+ SESSION_KEYS.SERVER_METADATA,
17043
+ this.serverUrl
17044
+ );
17045
+ const metadata = sessionStorage.getItem(key);
17046
+ if (!metadata) {
17047
+ return null;
17048
+ }
17049
+ return JSON.parse(metadata);
17050
+ }
17051
+ clear() {
17052
+ super.clear();
17053
+ sessionStorage.removeItem(
17054
+ getServerSpecificKey(SESSION_KEYS.SERVER_METADATA, this.serverUrl)
17055
+ );
17056
+ }
17057
+ }
17024
17058
  const oauthTransitions = {
17025
17059
  metadata_discovery: {
17026
17060
  canTransition: async () => true,
@@ -17049,7 +17083,7 @@ const oauthTransitions = {
17049
17083
  // we default to null, so swap it for undefined if not set
17050
17084
  resourceMetadata ?? void 0
17051
17085
  );
17052
- const metadata = await discoverOAuthMetadata(authServerUrl);
17086
+ const metadata = await discoverAuthorizationServerMetadata(authServerUrl);
17053
17087
  if (!metadata) {
17054
17088
  throw new Error("Failed to discover OAuth metadata");
17055
17089
  }
@@ -17075,11 +17109,14 @@ const oauthTransitions = {
17075
17109
  if (scopesSupported) {
17076
17110
  clientMetadata.scope = scopesSupported.join(" ");
17077
17111
  }
17078
- const fullInformation = await registerClient(context.serverUrl, {
17079
- metadata,
17080
- clientMetadata
17081
- });
17082
- context.provider.saveClientInformation(fullInformation);
17112
+ let fullInformation = await context.provider.clientInformation();
17113
+ if (!fullInformation) {
17114
+ fullInformation = await registerClient(context.serverUrl, {
17115
+ metadata,
17116
+ clientMetadata
17117
+ });
17118
+ context.provider.saveClientInformation(fullInformation);
17119
+ }
17083
17120
  context.updateState({
17084
17121
  oauthClientInfo: fullInformation,
17085
17122
  oauthStep: "authorization_redirect"
@@ -17091,10 +17128,10 @@ const oauthTransitions = {
17091
17128
  execute: async (context) => {
17092
17129
  const metadata = context.state.oauthMetadata;
17093
17130
  const clientInformation = context.state.oauthClientInfo;
17094
- let scope = void 0;
17095
- if (metadata.scopes_supported) {
17096
- scope = metadata.scopes_supported.join(" ");
17097
- }
17131
+ const scope = await discoverScopes(
17132
+ context.serverUrl,
17133
+ context.state.resourceMetadata ?? void 0
17134
+ );
17098
17135
  const { authorizationUrl, codeVerifier } = await startAuthorization(
17099
17136
  context.serverUrl,
17100
17137
  {
@@ -17102,6 +17139,7 @@ const oauthTransitions = {
17102
17139
  clientInformation,
17103
17140
  redirectUrl: context.provider.redirectUrl,
17104
17141
  scope,
17142
+ state: generateOAuthState(),
17105
17143
  resource: context.state.resource ?? void 0
17106
17144
  }
17107
17145
  );
@@ -17186,7 +17224,7 @@ function requireUri_all() {
17186
17224
  (function(module, exports) {
17187
17225
  (function(global2, factory) {
17188
17226
  factory(exports);
17189
- })(uri_all, function(exports2) {
17227
+ })(uri_all, (function(exports2) {
17190
17228
  function merge() {
17191
17229
  for (var _len = arguments.length, sets = Array(_len), _key = 0; _key < _len; _key++) {
17192
17230
  sets[_key] = arguments[_key];
@@ -17253,7 +17291,7 @@ function requireUri_all() {
17253
17291
  }
17254
17292
  var URI_PROTOCOL = buildExps(false);
17255
17293
  var IRI_PROTOCOL = buildExps(true);
17256
- var slicedToArray = /* @__PURE__ */ function() {
17294
+ var slicedToArray = /* @__PURE__ */ (function() {
17257
17295
  function sliceIterator(arr, i) {
17258
17296
  var _arr = [];
17259
17297
  var _n = true;
@@ -17285,7 +17323,7 @@ function requireUri_all() {
17285
17323
  throw new TypeError("Invalid attempt to destructure non-iterable instance");
17286
17324
  }
17287
17325
  };
17288
- }();
17326
+ })();
17289
17327
  var toConsumableArray = function(arr) {
17290
17328
  if (Array.isArray(arr)) {
17291
17329
  for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
@@ -18200,7 +18238,7 @@ function requireUri_all() {
18200
18238
  exports2.escapeComponent = escapeComponent;
18201
18239
  exports2.unescapeComponent = unescapeComponent;
18202
18240
  Object.defineProperty(exports2, "__esModule", { value: true });
18203
- });
18241
+ }));
18204
18242
  })(uri_all$1, uri_all$1.exports);
18205
18243
  return uri_all$1.exports;
18206
18244
  }
@@ -18794,7 +18832,7 @@ function requireFastJsonStableStringify() {
18794
18832
  if (!opts) opts = {};
18795
18833
  if (typeof opts === "function") opts = { cmp: opts };
18796
18834
  var cycles = typeof opts.cycles === "boolean" ? opts.cycles : false;
18797
- var cmp = opts.cmp && /* @__PURE__ */ function(f) {
18835
+ var cmp = opts.cmp && /* @__PURE__ */ (function(f) {
18798
18836
  return function(node) {
18799
18837
  return function(a, b) {
18800
18838
  var aobj = { key: a, value: node[a] };
@@ -18802,9 +18840,9 @@ function requireFastJsonStableStringify() {
18802
18840
  return f(aobj, bobj);
18803
18841
  };
18804
18842
  };
18805
- }(opts.cmp);
18843
+ })(opts.cmp);
18806
18844
  var seen2 = [];
18807
- return function stringify(node) {
18845
+ return (function stringify(node) {
18808
18846
  if (node && node.toJSON && typeof node.toJSON === "function") {
18809
18847
  node = node.toJSON();
18810
18848
  }
@@ -18837,7 +18875,7 @@ function requireFastJsonStableStringify() {
18837
18875
  }
18838
18876
  seen2.splice(seenIndex, 1);
18839
18877
  return "{" + out + "}";
18840
- }(data2);
18878
+ })(data2);
18841
18879
  };
18842
18880
  return fastJsonStableStringify;
18843
18881
  }
@@ -23290,6 +23328,33 @@ function isPropertyRequired(propertyName, schema) {
23290
23328
  var _a;
23291
23329
  return ((_a = schema.required) == null ? void 0 : _a.includes(propertyName)) ?? false;
23292
23330
  }
23331
+ function normalizeUnionType(schema) {
23332
+ if (schema.anyOf && schema.anyOf.length === 2 && schema.anyOf.some((t) => t.type === "string") && schema.anyOf.some((t) => t.type === "null")) {
23333
+ return { ...schema, type: "string", anyOf: void 0 };
23334
+ }
23335
+ if (schema.anyOf && schema.anyOf.length === 2 && schema.anyOf.some((t) => t.type === "boolean") && schema.anyOf.some((t) => t.type === "null")) {
23336
+ return { ...schema, type: "boolean", anyOf: void 0 };
23337
+ }
23338
+ if (schema.anyOf && schema.anyOf.length === 2 && schema.anyOf.some((t) => t.type === "number") && schema.anyOf.some((t) => t.type === "null")) {
23339
+ return { ...schema, type: "number", anyOf: void 0 };
23340
+ }
23341
+ if (schema.anyOf && schema.anyOf.length === 2 && schema.anyOf.some((t) => t.type === "integer") && schema.anyOf.some((t) => t.type === "null")) {
23342
+ return { ...schema, type: "integer", anyOf: void 0 };
23343
+ }
23344
+ if (Array.isArray(schema.type) && schema.type.length === 2 && schema.type.includes("string") && schema.type.includes("null")) {
23345
+ return { ...schema, type: "string" };
23346
+ }
23347
+ if (Array.isArray(schema.type) && schema.type.length === 2 && schema.type.includes("boolean") && schema.type.includes("null")) {
23348
+ return { ...schema, type: "boolean" };
23349
+ }
23350
+ if (Array.isArray(schema.type) && schema.type.length === 2 && schema.type.includes("number") && schema.type.includes("null")) {
23351
+ return { ...schema, type: "number" };
23352
+ }
23353
+ if (Array.isArray(schema.type) && schema.type.length === 2 && schema.type.includes("integer") && schema.type.includes("null")) {
23354
+ return { ...schema, type: "integer" };
23355
+ }
23356
+ return schema;
23357
+ }
23293
23358
  const DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
23294
23359
  class Protocol {
23295
23360
  constructor(_options) {
@@ -23404,10 +23469,11 @@ class Protocol {
23404
23469
  Promise.resolve().then(() => handler(notification)).catch((error) => this._onerror(new Error(`Uncaught error in notification handler: ${error}`)));
23405
23470
  }
23406
23471
  _onrequest(request, extra) {
23407
- var _a, _b, _c, _d;
23472
+ var _a, _b;
23408
23473
  const handler = (_a = this._requestHandlers.get(request.method)) !== null && _a !== void 0 ? _a : this.fallbackRequestHandler;
23474
+ const capturedTransport = this._transport;
23409
23475
  if (handler === void 0) {
23410
- (_b = this._transport) === null || _b === void 0 ? void 0 : _b.send({
23476
+ capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
23411
23477
  jsonrpc: "2.0",
23412
23478
  id: request.id,
23413
23479
  error: {
@@ -23421,8 +23487,8 @@ class Protocol {
23421
23487
  this._requestHandlerAbortControllers.set(request.id, abortController);
23422
23488
  const fullExtra = {
23423
23489
  signal: abortController.signal,
23424
- sessionId: (_c = this._transport) === null || _c === void 0 ? void 0 : _c.sessionId,
23425
- _meta: (_d = request.params) === null || _d === void 0 ? void 0 : _d._meta,
23490
+ sessionId: capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.sessionId,
23491
+ _meta: (_b = request.params) === null || _b === void 0 ? void 0 : _b._meta,
23426
23492
  sendNotification: (notification) => this.notification(notification, { relatedRequestId: request.id }),
23427
23493
  sendRequest: (r2, resultSchema, options) => this.request(r2, resultSchema, { ...options, relatedRequestId: request.id }),
23428
23494
  authInfo: extra === null || extra === void 0 ? void 0 : extra.authInfo,
@@ -23430,26 +23496,25 @@ class Protocol {
23430
23496
  requestInfo: extra === null || extra === void 0 ? void 0 : extra.requestInfo
23431
23497
  };
23432
23498
  Promise.resolve().then(() => handler(request, fullExtra)).then((result) => {
23433
- var _a2;
23434
23499
  if (abortController.signal.aborted) {
23435
23500
  return;
23436
23501
  }
23437
- return (_a2 = this._transport) === null || _a2 === void 0 ? void 0 : _a2.send({
23502
+ return capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
23438
23503
  result,
23439
23504
  jsonrpc: "2.0",
23440
23505
  id: request.id
23441
23506
  });
23442
23507
  }, (error) => {
23443
- var _a2, _b2;
23508
+ var _a2;
23444
23509
  if (abortController.signal.aborted) {
23445
23510
  return;
23446
23511
  }
23447
- return (_a2 = this._transport) === null || _a2 === void 0 ? void 0 : _a2.send({
23512
+ return capturedTransport === null || capturedTransport === void 0 ? void 0 : capturedTransport.send({
23448
23513
  jsonrpc: "2.0",
23449
23514
  id: request.id,
23450
23515
  error: {
23451
23516
  code: Number.isSafeInteger(error["code"]) ? error["code"] : ErrorCode.InternalError,
23452
- message: (_b2 = error.message) !== null && _b2 !== void 0 ? _b2 : "Internal error"
23517
+ message: (_a2 = error.message) !== null && _a2 !== void 0 ? _a2 : "Internal error"
23453
23518
  }
23454
23519
  });
23455
23520
  }).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
@@ -24779,7 +24844,7 @@ const StdErrNotificationSchema = NotificationSchema.extend({
24779
24844
  ClientNotificationSchema.or(
24780
24845
  StdErrNotificationSchema
24781
24846
  ).or(ServerNotificationSchema).or(NotificationSchema);
24782
- const version$1 = "0.16.2";
24847
+ const version$1 = "0.16.4";
24783
24848
  const packageJson = {
24784
24849
  version: version$1
24785
24850
  };
@@ -24914,7 +24979,8 @@ function useConnection({
24914
24979
  onStdErrNotification,
24915
24980
  onPendingRequest,
24916
24981
  onElicitationRequest,
24917
- getRoots
24982
+ getRoots,
24983
+ defaultLoggingLevel
24918
24984
  }) {
24919
24985
  const [connectionStatus, setConnectionStatus] = reactExports.useState("disconnected");
24920
24986
  const { toast: toast2 } = useToast();
@@ -24992,7 +25058,7 @@ function useConnection({
24992
25058
  throw e;
24993
25059
  }
24994
25060
  };
24995
- const handleCompletion = async (ref2, argName, value, signal) => {
25061
+ const handleCompletion = async (ref2, argName, value, context, signal) => {
24996
25062
  if (!mcpClient || !completionsSupported) {
24997
25063
  return [];
24998
25064
  }
@@ -25006,6 +25072,11 @@ function useConnection({
25006
25072
  ref: ref2
25007
25073
  }
25008
25074
  };
25075
+ if (context) {
25076
+ request["params"]["context"] = {
25077
+ arguments: context
25078
+ };
25079
+ }
25009
25080
  try {
25010
25081
  const response = await makeRequest(request, CompleteResultSchema, {
25011
25082
  signal,
@@ -25077,9 +25148,20 @@ function useConnection({
25077
25148
  const handleAuthError = async (error) => {
25078
25149
  if (is401Error(error)) {
25079
25150
  const serverAuthProvider = new InspectorOAuthClientProvider(sseUrl);
25151
+ let scope = oauthScope == null ? void 0 : oauthScope.trim();
25152
+ if (!scope) {
25153
+ let resourceMetadata;
25154
+ try {
25155
+ resourceMetadata = await discoverOAuthProtectedResourceMetadata(
25156
+ new URL("/", sseUrl)
25157
+ );
25158
+ } catch {
25159
+ }
25160
+ scope = await discoverScopes(sseUrl, resourceMetadata);
25161
+ }
25080
25162
  const result = await auth(serverAuthProvider, {
25081
25163
  serverUrl: sseUrl,
25082
- scope: oauthScope
25164
+ scope
25083
25165
  });
25084
25166
  return result === "AUTHORIZED";
25085
25167
  }
@@ -25108,6 +25190,7 @@ function useConnection({
25108
25190
  setConnectionStatus("error-connecting-to-proxy");
25109
25191
  return;
25110
25192
  }
25193
+ let lastRequest = "";
25111
25194
  try {
25112
25195
  const headers = {};
25113
25196
  const serverAuthProvider = new InspectorOAuthClientProvider(sseUrl);
@@ -25268,6 +25351,11 @@ function useConnection({
25268
25351
  return { roots: getRoots() };
25269
25352
  });
25270
25353
  }
25354
+ if ((capabilities == null ? void 0 : capabilities.logging) && defaultLoggingLevel) {
25355
+ lastRequest = "logging/setLevel";
25356
+ await client2.setLoggingLevel(defaultLoggingLevel);
25357
+ lastRequest = "";
25358
+ }
25271
25359
  if (onElicitationRequest) {
25272
25360
  client2.setRequestHandler(ElicitRequestSchema, async (request) => {
25273
25361
  return new Promise((resolve) => {
@@ -25278,6 +25366,13 @@ function useConnection({
25278
25366
  setMcpClient(client2);
25279
25367
  setConnectionStatus("connected");
25280
25368
  } catch (e) {
25369
+ if (lastRequest === "logging/setLevel" && e instanceof McpError && e.code === ErrorCode.MethodNotFound) {
25370
+ toast2({
25371
+ title: "Error",
25372
+ description: `Server declares logging capability but doesn't implement method: "${lastRequest}"`,
25373
+ variant: "destructive"
25374
+ });
25375
+ }
25281
25376
  console.error(e);
25282
25377
  setConnectionStatus("error");
25283
25378
  }
@@ -29552,7 +29647,7 @@ const flip$2 = function(options) {
29552
29647
  const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
29553
29648
  if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
29554
29649
  // overflows the main axis.
29555
- overflowsData.every((d) => d.overflows[0] > 0 && getSideAxis(d.placement) === initialSideAxis)) {
29650
+ overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
29556
29651
  return {
29557
29652
  data: {
29558
29653
  index: nextIndex,
@@ -31042,8 +31137,13 @@ var PopperAnchor = reactExports.forwardRef(
31042
31137
  const context = usePopperContext(ANCHOR_NAME$1, __scopePopper);
31043
31138
  const ref2 = reactExports.useRef(null);
31044
31139
  const composedRefs = useComposedRefs(forwardedRef, ref2);
31140
+ const anchorRef = reactExports.useRef(null);
31045
31141
  reactExports.useEffect(() => {
31046
- context.onAnchorChange((virtualRef == null ? void 0 : virtualRef.current) || ref2.current);
31142
+ const previousAnchor = anchorRef.current;
31143
+ anchorRef.current = (virtualRef == null ? void 0 : virtualRef.current) || ref2.current;
31144
+ if (previousAnchor !== anchorRef.current) {
31145
+ context.onAnchorChange(anchorRef.current);
31146
+ }
31047
31147
  });
31048
31148
  return virtualRef ? null : /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { ...anchorProps, ref: composedRefs });
31049
31149
  }
@@ -31767,7 +31867,7 @@ function useCompletionState(handleCompletion, completionsSupported = true, debou
31767
31867
  }, [cleanup]);
31768
31868
  const requestCompletions = reactExports.useMemo(() => {
31769
31869
  return debounce(
31770
- async (ref2, argName, value) => {
31870
+ async (ref2, argName, value, context) => {
31771
31871
  if (!completionsSupported) {
31772
31872
  return;
31773
31873
  }
@@ -31779,10 +31879,14 @@ function useCompletionState(handleCompletion, completionsSupported = true, debou
31779
31879
  loading: { ...prev.loading, [argName]: true }
31780
31880
  }));
31781
31881
  try {
31882
+ if (context !== void 0) {
31883
+ delete context[argName];
31884
+ }
31782
31885
  const values = await handleCompletion(
31783
31886
  ref2,
31784
31887
  argName,
31785
31888
  value,
31889
+ context,
31786
31890
  abortController.signal
31787
31891
  );
31788
31892
  if (!abortController.signal.aborted) {
@@ -31793,6 +31897,7 @@ function useCompletionState(handleCompletion, completionsSupported = true, debou
31793
31897
  }));
31794
31898
  }
31795
31899
  } catch {
31900
+ console.error("completion failed");
31796
31901
  if (!abortController.signal.aborted) {
31797
31902
  setState((prev) => ({
31798
31903
  ...prev,
@@ -31848,7 +31953,8 @@ const PromptsTab = ({
31848
31953
  name: selectedPrompt.name
31849
31954
  },
31850
31955
  argName,
31851
- value
31956
+ value,
31957
+ promptArgs
31852
31958
  );
31853
31959
  }
31854
31960
  };
@@ -32174,7 +32280,8 @@ const ResourcesTab = ({
32174
32280
  uri: selectedTemplate.uriTemplate
32175
32281
  },
32176
32282
  key,
32177
- value
32283
+ value,
32284
+ templateValues
32178
32285
  );
32179
32286
  }
32180
32287
  };
@@ -32412,7 +32519,7 @@ function requireLib() {
32412
32519
  };
32413
32520
  return __assign2.apply(this, arguments);
32414
32521
  };
32415
- var __createBinding = lib && lib.__createBinding || (Object.create ? function(o, m2, k2, k22) {
32522
+ var __createBinding = lib && lib.__createBinding || (Object.create ? (function(o, m2, k2, k22) {
32416
32523
  if (k22 === void 0) k22 = k2;
32417
32524
  var desc = Object.getOwnPropertyDescriptor(m2, k2);
32418
32525
  if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
@@ -32421,13 +32528,13 @@ function requireLib() {
32421
32528
  } };
32422
32529
  }
32423
32530
  Object.defineProperty(o, k22, desc);
32424
- } : function(o, m2, k2, k22) {
32531
+ }) : (function(o, m2, k2, k22) {
32425
32532
  if (k22 === void 0) k22 = k2;
32426
32533
  o[k22] = m2[k2];
32427
- });
32428
- var __setModuleDefault = lib && lib.__setModuleDefault || (Object.create ? function(o, v) {
32534
+ }));
32535
+ var __setModuleDefault = lib && lib.__setModuleDefault || (Object.create ? (function(o, v) {
32429
32536
  Object.defineProperty(o, "default", { enumerable: true, value: v });
32430
- } : function(o, v) {
32537
+ }) : function(o, v) {
32431
32538
  o["default"] = v;
32432
32539
  });
32433
32540
  var __importStar = lib && lib.__importStar || function(mod) {
@@ -32813,7 +32920,7 @@ function requirePrism() {
32813
32920
  * @namespace
32814
32921
  * @public
32815
32922
  */
32816
- var Prism2 = function(_self2) {
32923
+ var Prism2 = (function(_self2) {
32817
32924
  var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
32818
32925
  var uniqueId = 0;
32819
32926
  var plainTextGrammar = {};
@@ -33698,7 +33805,7 @@ function requirePrism() {
33698
33805
  }
33699
33806
  }
33700
33807
  return _;
33701
- }(_self);
33808
+ })(_self);
33702
33809
  if (module.exports) {
33703
33810
  module.exports = Prism2;
33704
33811
  }
@@ -34329,12 +34436,18 @@ const JsonEditor = ({
34329
34436
  displayError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-red-500 mt-1", children: displayError })
34330
34437
  ] });
34331
34438
  };
34439
+ const isTypeSupported = (type2, supportedTypes) => {
34440
+ if (Array.isArray(type2)) {
34441
+ return type2.every((t) => supportedTypes.includes(t));
34442
+ }
34443
+ return typeof type2 === "string" && supportedTypes.includes(type2);
34444
+ };
34332
34445
  const isSimpleObject = (schema) => {
34333
34446
  const supportedTypes = ["string", "number", "integer", "boolean", "null"];
34334
- if (schema.type && supportedTypes.includes(schema.type)) return true;
34447
+ if (schema.type && isTypeSupported(schema.type, supportedTypes)) return true;
34335
34448
  if (schema.type === "object") {
34336
34449
  return Object.values(schema.properties ?? {}).every(
34337
- (prop) => prop.type && supportedTypes.includes(prop.type)
34450
+ (prop) => prop.type && isTypeSupported(prop.type, supportedTypes)
34338
34451
  );
34339
34452
  }
34340
34453
  if (schema.type === "array") {
@@ -34457,7 +34570,11 @@ const DynamicJsonForm = ({
34457
34570
  );
34458
34571
  }
34459
34572
  const isRequired = ((_a = parentSchema == null ? void 0 : parentSchema.required) == null ? void 0 : _a.includes(propertyName || "")) ?? false;
34460
- switch (propSchema.type) {
34573
+ let fieldType = propSchema.type;
34574
+ if (Array.isArray(fieldType)) {
34575
+ fieldType = fieldType.find((t) => t !== "null") ?? fieldType[0];
34576
+ }
34577
+ switch (fieldType) {
34461
34578
  case "string": {
34462
34579
  if (propSchema.oneOf && propSchema.oneOf.every(
34463
34580
  (option) => typeof option.const === "string" && typeof option.title === "string"
@@ -34605,6 +34722,8 @@ const DynamicJsonForm = ({
34605
34722
  required: isRequired
34606
34723
  }
34607
34724
  );
34725
+ case "null":
34726
+ return null;
34608
34727
  case "object":
34609
34728
  if (!propSchema.properties) {
34610
34729
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -36263,7 +36382,7 @@ const useTheme = () => {
36263
36382
  [theme, setThemeWithSideEffect]
36264
36383
  );
36265
36384
  };
36266
- const version = "0.16.2";
36385
+ const version = "0.16.4";
36267
36386
  var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
36268
36387
  createPopperScope
36269
36388
  ]);
@@ -37917,6 +38036,10 @@ const ToolResults = ({
37917
38036
  )
37918
38037
  ] })
37919
38038
  ] }),
38039
+ structuredResult._meta && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
38040
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h5", { className: "font-semibold mb-2 text-sm", children: "Meta:" }),
38041
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 dark:bg-gray-900 p-3 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: structuredResult._meta }) })
38042
+ ] }),
37920
38043
  !structuredResult.structuredContent && validationResult && !validationResult.isValid && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 p-2 rounded text-sm", children: [
37921
38044
  "✗ Validation Error: ",
37922
38045
  validationResult.error
@@ -37980,6 +38103,7 @@ const ToolResults = ({
37980
38103
  }
37981
38104
  return null;
37982
38105
  };
38106
+ const hasMeta = (tool) => typeof tool._meta !== "undefined";
37983
38107
  const ToolsTab = ({
37984
38108
  tools,
37985
38109
  listTools,
@@ -37995,6 +38119,7 @@ const ToolsTab = ({
37995
38119
  const [params, setParams] = reactExports.useState({});
37996
38120
  const [isToolRunning, setIsToolRunning] = reactExports.useState(false);
37997
38121
  const [isOutputSchemaExpanded, setIsOutputSchemaExpanded] = reactExports.useState(false);
38122
+ const [isMetaExpanded, setIsMetaExpanded] = reactExports.useState(false);
37998
38123
  reactExports.useEffect(() => {
37999
38124
  const params2 = Object.entries(
38000
38125
  (selectedTool == null ? void 0 : selectedTool.inputSchema.properties) ?? []
@@ -38034,7 +38159,7 @@ const ToolsTab = ({
38034
38159
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: selectedTool.description }),
38035
38160
  Object.entries(selectedTool.inputSchema.properties ?? []).map(
38036
38161
  ([key, value]) => {
38037
- const prop = value;
38162
+ const prop = normalizeUnionType(value);
38038
38163
  const inputSchema = selectedTool.inputSchema;
38039
38164
  const required2 = isPropertyRequired(key, inputSchema);
38040
38165
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
@@ -38079,7 +38204,7 @@ const ToolsTab = ({
38079
38204
  value: params[key] ?? "",
38080
38205
  onChange: (e) => setParams({
38081
38206
  ...params,
38082
- [key]: e.target.value
38207
+ [key]: e.target.value === "" ? void 0 : e.target.value
38083
38208
  }),
38084
38209
  className: "mt-1"
38085
38210
  }
@@ -38166,6 +38291,34 @@ const ToolsTab = ({
38166
38291
  }
38167
38292
  )
38168
38293
  ] }),
38294
+ selectedTool && hasMeta(selectedTool) && selectedTool._meta && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 dark:bg-gray-900 p-3 rounded-lg", children: [
38295
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
38296
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-semibold", children: "Meta:" }),
38297
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
38298
+ Button,
38299
+ {
38300
+ size: "sm",
38301
+ variant: "ghost",
38302
+ onClick: () => setIsMetaExpanded(!isMetaExpanded),
38303
+ className: "h-6 px-2",
38304
+ children: isMetaExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
38305
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "h-3 w-3 mr-1" }),
38306
+ "Collapse"
38307
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
38308
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "h-3 w-3 mr-1" }),
38309
+ "Expand"
38310
+ ] })
38311
+ }
38312
+ )
38313
+ ] }),
38314
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
38315
+ "div",
38316
+ {
38317
+ className: `transition-all ${isMetaExpanded ? "" : "max-h-[8rem] overflow-y-auto"}`,
38318
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(JsonView, { data: selectedTool._meta })
38319
+ }
38320
+ )
38321
+ ] }),
38169
38322
  /* @__PURE__ */ jsxRuntimeExports.jsx(
38170
38323
  Button,
38171
38324
  {
@@ -38471,7 +38624,8 @@ const App = () => {
38471
38624
  setActiveTab("elicitations");
38472
38625
  window.location.hash = "elicitations";
38473
38626
  },
38474
- getRoots: () => rootsRef.current
38627
+ getRoots: () => rootsRef.current,
38628
+ defaultLoggingLevel: logLevel
38475
38629
  });
38476
38630
  reactExports.useEffect(() => {
38477
38631
  if (serverCapabilities) {
@@ -38624,6 +38778,14 @@ const App = () => {
38624
38778
  if (data2.defaultArgs) {
38625
38779
  setArgs(data2.defaultArgs);
38626
38780
  }
38781
+ if (data2.defaultTransport) {
38782
+ setTransportType(
38783
+ data2.defaultTransport
38784
+ );
38785
+ }
38786
+ if (data2.defaultServerUrl) {
38787
+ setSseUrl(data2.defaultServerUrl);
38788
+ }
38627
38789
  }).catch(
38628
38790
  (error) => console.error("Error fetching default environment:", error)
38629
38791
  );
@@ -38632,10 +38794,17 @@ const App = () => {
38632
38794
  rootsRef.current = roots;
38633
38795
  }, [roots]);
38634
38796
  reactExports.useEffect(() => {
38635
- if (!window.location.hash) {
38636
- window.location.hash = "resources";
38797
+ if (mcpClient && !window.location.hash) {
38798
+ const defaultTab = (serverCapabilities == null ? void 0 : serverCapabilities.resources) ? "resources" : (serverCapabilities == null ? void 0 : serverCapabilities.prompts) ? "prompts" : (serverCapabilities == null ? void 0 : serverCapabilities.tools) ? "tools" : "ping";
38799
+ window.location.hash = defaultTab;
38800
+ } else if (!mcpClient && window.location.hash) {
38801
+ window.history.replaceState(
38802
+ null,
38803
+ "",
38804
+ window.location.pathname + window.location.search
38805
+ );
38637
38806
  }
38638
- }, []);
38807
+ }, [mcpClient, serverCapabilities]);
38639
38808
  reactExports.useEffect(() => {
38640
38809
  const handleHashChange = () => {
38641
38810
  const hash = window.location.hash.slice(1);
@@ -38879,13 +39048,13 @@ const App = () => {
38879
39048
  ) });
38880
39049
  if (window.location.pathname === "/oauth/callback") {
38881
39050
  const OAuthCallback = React.lazy(
38882
- () => __vitePreload(() => import("./OAuthCallback-CC1cu0Zx.js"), true ? __vite__mapDeps([0,1]) : void 0)
39051
+ () => __vitePreload(() => import("./OAuthCallback-DyaAiF-O.js"), true ? [] : void 0)
38883
39052
  );
38884
39053
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
38885
39054
  }
38886
39055
  if (window.location.pathname === "/oauth/callback/debug") {
38887
39056
  const OAuthDebugCallback = React.lazy(
38888
- () => __vitePreload(() => import("./OAuthDebugCallback-_4BLxVDe.js"), true ? __vite__mapDeps([2,1]) : void 0)
39057
+ () => __vitePreload(() => import("./OAuthDebugCallback-BD-zJllm.js"), true ? [] : void 0)
38889
39058
  );
38890
39059
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
38891
39060
  }
@@ -39253,7 +39422,9 @@ export {
39253
39422
  InspectorOAuthClientProvider as I,
39254
39423
  SESSION_KEYS as S,
39255
39424
  auth as a,
39425
+ generateOAuthErrorDescription as g,
39256
39426
  jsxRuntimeExports as j,
39427
+ parseOAuthCallbackParams as p,
39257
39428
  reactExports as r,
39258
39429
  useToast as u
39259
39430
  };
package/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/mcp.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>MCP Inspector</title>
8
- <script type="module" crossorigin src="/assets/index-DLtnCiTW.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-BtsSr_hT.css">
8
+ <script type="module" crossorigin src="/assets/index-MFoeZZBS.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-BWZfLo5E.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root" class="w-full"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelcontextprotocol/inspector-client",
3
- "version": "0.16.2",
3
+ "version": "0.16.4",
4
4
  "description": "Client-side application for the Model Context Protocol inspector",
5
5
  "license": "MIT",
6
6
  "author": "Anthropic, PBC (https://anthropic.com)",
@@ -25,7 +25,7 @@
25
25
  "cleanup:e2e": "node e2e/global-teardown.js"
26
26
  },
27
27
  "dependencies": {
28
- "@modelcontextprotocol/sdk": "^1.17.0",
28
+ "@modelcontextprotocol/sdk": "^1.17.2",
29
29
  "@radix-ui/react-checkbox": "^1.1.4",
30
30
  "@radix-ui/react-dialog": "^1.1.3",
31
31
  "@radix-ui/react-icons": "^1.3.0",
@@ -49,19 +49,19 @@
49
49
  "serve-handler": "^6.1.6",
50
50
  "tailwind-merge": "^2.5.3",
51
51
  "tailwindcss-animate": "^1.0.7",
52
- "zod": "^3.23.8"
52
+ "zod": "^3.25.76"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@eslint/js": "^9.11.1",
56
56
  "@testing-library/jest-dom": "^6.6.3",
57
57
  "@testing-library/react": "^16.2.0",
58
58
  "@types/jest": "^29.5.14",
59
- "@types/node": "^22.7.5",
59
+ "@types/node": "^22.17.0",
60
60
  "@types/prismjs": "^1.26.5",
61
- "@types/react": "^18.3.10",
61
+ "@types/react": "^18.3.23",
62
62
  "@types/react-dom": "^18.3.0",
63
63
  "@types/serve-handler": "^6.1.4",
64
- "@vitejs/plugin-react": "^4.3.2",
64
+ "@vitejs/plugin-react": "^4.7.0",
65
65
  "autoprefixer": "^10.4.20",
66
66
  "co": "^4.6.0",
67
67
  "eslint": "^9.11.1",
@@ -70,11 +70,11 @@
70
70
  "globals": "^15.9.0",
71
71
  "jest": "^29.7.0",
72
72
  "jest-environment-jsdom": "^29.7.0",
73
- "postcss": "^8.4.47",
73
+ "postcss": "^8.5.6",
74
74
  "tailwindcss": "^3.4.13",
75
- "ts-jest": "^29.2.6",
75
+ "ts-jest": "^29.4.0",
76
76
  "typescript": "^5.5.3",
77
- "typescript-eslint": "^8.7.0",
78
- "vite": "^6.3.0"
77
+ "typescript-eslint": "^8.38.0",
78
+ "vite": "^6.3.5"
79
79
  }
80
80
  }
@@ -1,33 +0,0 @@
1
- const parseOAuthCallbackParams = (location) => {
2
- const params = new URLSearchParams(location);
3
- const code = params.get("code");
4
- if (code) {
5
- return { successful: true, code };
6
- }
7
- const error = params.get("error");
8
- const error_description = params.get("error_description");
9
- const error_uri = params.get("error_uri");
10
- if (error) {
11
- return { successful: false, error, error_description, error_uri };
12
- }
13
- return {
14
- successful: false,
15
- error: "invalid_request",
16
- error_description: "Missing code or error in response",
17
- error_uri: null
18
- };
19
- };
20
- const generateOAuthErrorDescription = (params) => {
21
- const error = params.error;
22
- const errorDescription = params.error_description;
23
- const errorUri = params.error_uri;
24
- return [
25
- `Error: ${error}.`,
26
- errorDescription ? `Details: ${errorDescription}.` : "",
27
- errorUri ? `More info: ${errorUri}.` : ""
28
- ].filter(Boolean).join("\n");
29
- };
30
- export {
31
- generateOAuthErrorDescription as g,
32
- parseOAuthCallbackParams as p
33
- };